diff --git a/.gitignore b/.gitignore index 56eef1249b..c289d5a4b4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,8 @@ .vscode .idea /generated +*.srs +*.log +*.json +*.yul +*.sol diff --git a/Cargo.lock b/Cargo.lock index d4746e56aa..fa8e302c1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2903,10 +2903,16 @@ dependencies = [ "ethers-core", "ethers-signers", "external-tracer", + "halo2_proofs 0.2.0", "itertools", "lazy_static", + "libsecp256k1", + "num", + "num-bigint", + "once_cell", "rand", "rand_chacha", + "sha3 0.10.7", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index be096fc2fb..7958f3ddb2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ members = [ "eth-types", "external-tracer", "mock", - "testool" + "testool", ] [patch.crates-io] diff --git a/Makefile b/Makefile index 6dcf6e8420..92abd72d92 100644 --- a/Makefile +++ b/Makefile @@ -23,9 +23,9 @@ fmt: ## Check whether the code is formated correctly test: ## Run tests for all the workspace members # Run light tests - @cargo test --release --all --all-features --exclude integration-tests --exclude circuit-benchmarks + @cargo test --release --all --all-features --exclude integration-tests --exclude circuit-benchmarks --exclude testool # Run heavy tests serially to avoid OOM - @cargo test --release --all --all-features --exclude integration-tests --exclude circuit-benchmarks serial_ -- --ignored --test-threads 1 + @cargo test --release --all --all-features --exclude integration-tests --exclude circuit-benchmarks --exclude testool serial_ -- --ignored # --test-threads 1 test_doc: ## Test the docs diff --git a/bus-mapping/src/circuit_input_builder.rs b/bus-mapping/src/circuit_input_builder.rs index 0b4c0ae3a8..845a9bee89 100644 --- a/bus-mapping/src/circuit_input_builder.rs +++ b/bus-mapping/src/circuit_input_builder.rs @@ -6,6 +6,7 @@ mod block; mod call; mod execution; mod input_state_ref; +mod protocol_instance; #[cfg(test)] mod tracer_tests; mod transaction; @@ -34,6 +35,7 @@ pub use execution::{ pub use input_state_ref::CircuitInputStateRef; use itertools::Itertools; use log::warn; +pub use protocol_instance::{left_shift, MetaHash, ProtocolInstance, ANCHOR_TX_METHOD_SIGNATURE}; use std::collections::HashMap; pub use transaction::{Transaction, TransactionContext}; @@ -75,7 +77,7 @@ impl Default for CircuitsParams { fn default() -> Self { CircuitsParams { max_rws: 1000, - max_txs: 1, + max_txs: 2, // more one for anchor max_calldata: 256, // TODO: Check whether this value is correct or we should increase/decrease based on // this lib tests @@ -151,6 +153,7 @@ impl<'a> CircuitInputBuilder { /// Create a new Transaction from a [`eth_types::Transaction`]. pub fn new_tx( &mut self, + eth_block: &EthBlock, eth_tx: ð_types::Transaction, is_success: bool, ) -> Result { @@ -167,7 +170,15 @@ impl<'a> CircuitInputBuilder { ), ); - Transaction::new(call_id, &self.sdb, &mut self.code_db, eth_tx, is_success) + Transaction::new( + call_id, + &self.sdb, + &mut self.code_db, + eth_block, + eth_tx, + is_success, + self.block.is_taiko(), + ) } /// Iterate over all generated CallContext RwCounterEndOfReversion @@ -197,25 +208,14 @@ impl<'a> CircuitInputBuilder { &mut self, eth_block: &EthBlock, geth_traces: &[eth_types::GethExecTrace], - ) -> Result<(), Error> { - self.handle_block_with_anchor(eth_block, geth_traces, false) - } - - /// Handle a block by handling each transaction to generate all the - /// associated operations. - pub fn handle_block_with_anchor( - &mut self, - eth_block: &EthBlock, - geth_traces: &[eth_types::GethExecTrace], - has_anchor_tx: bool, ) -> Result<(), Error> { // accumulates gas across all txs in the block for (tx_index, tx) in eth_block.transactions.iter().enumerate() { let geth_trace = &geth_traces[tx_index]; self.handle_tx( + eth_block, tx, geth_trace, - has_anchor_tx && tx_index == 0, tx_index + 1 == eth_block.transactions.len(), )?; } @@ -279,13 +279,13 @@ impl<'a> CircuitInputBuilder { /// generated operations. fn handle_tx( &mut self, + eth_block: &EthBlock, eth_tx: ð_types::Transaction, geth_trace: &GethExecTrace, - is_anchor_tx: bool, is_last_tx: bool, ) -> Result<(), Error> { - let mut tx = self.new_tx(eth_tx, !geth_trace.failed)?; - let mut tx_ctx = TransactionContext::new(eth_tx, geth_trace, is_anchor_tx, is_last_tx)?; + let mut tx = self.new_tx(eth_block, eth_tx, !geth_trace.failed)?; + let mut tx_ctx = TransactionContext::new(eth_tx, geth_trace, is_last_tx)?; // Generate BeginTx step let begin_tx_step = gen_associated_steps( @@ -409,12 +409,14 @@ pub struct BuilderClient { cli: GethClient

, chain_id: Word, circuits_params: CircuitsParams, + protocol_instance: Option, } /// Get State Accesses from TxExecTraces pub fn get_state_accesses( eth_block: &EthBlock, geth_traces: &[eth_types::GethExecTrace], + protocol_instance: &Option, ) -> Result { let mut block_access_trace = vec![Access::new( None, @@ -430,6 +432,15 @@ pub fn get_state_accesses( let tx_access_trace = gen_state_access_trace(eth_block, tx, geth_trace)?; block_access_trace.extend(tx_access_trace); } + if let Some(pi) = protocol_instance { + block_access_trace.push(Access::new( + None, + RW::WRITE, + AccessValue::Account { + address: pi.meta_hash.treasury, + }, + )); + } Ok(AccessSet::from(block_access_trace)) } @@ -468,6 +479,7 @@ impl BuilderClient

{ pub async fn new( client: GethClient

, circuits_params: CircuitsParams, + protocol_instance: Option, ) -> Result { let chain_id = client.get_chain_id().await?; @@ -475,6 +487,7 @@ impl BuilderClient

{ cli: client, chain_id: chain_id.into(), circuits_params, + protocol_instance, }) } @@ -526,8 +539,9 @@ impl BuilderClient

{ pub fn get_state_accesses( eth_block: &EthBlock, geth_traces: &[eth_types::GethExecTrace], + protocol_instance: &Option, ) -> Result { - get_state_accesses(eth_block, geth_traces) + get_state_accesses(eth_block, geth_traces, protocol_instance) } /// Step 3. Query geth for all accounts, storage keys, and codes from @@ -584,30 +598,6 @@ impl BuilderClient

{ geth_traces: &[eth_types::GethExecTrace], history_hashes: Vec, prev_state_root: Word, - ) -> Result { - self.gen_inputs_from_state_with_anchor( - sdb, - code_db, - eth_block, - geth_traces, - history_hashes, - prev_state_root, - false, - ) - } - - /// Step 5. For each step in TxExecTraces, gen the associated ops and state - /// circuit inputs - #[allow(clippy::too_many_arguments)] - pub fn gen_inputs_from_state_with_anchor( - &self, - sdb: StateDB, - code_db: CodeDB, - eth_block: &EthBlock, - geth_traces: &[eth_types::GethExecTrace], - history_hashes: Vec, - prev_state_root: Word, - has_anchor_tx: bool, ) -> Result { let block = Block::new( self.chain_id, @@ -615,9 +605,10 @@ impl BuilderClient

{ prev_state_root, eth_block, self.circuits_params, + self.protocol_instance.clone(), )?; let mut builder = CircuitInputBuilder::new(sdb, code_db, block); - builder.handle_block_with_anchor(eth_block, geth_traces, has_anchor_tx)?; + builder.handle_block(eth_block, geth_traces)?; Ok(builder) } @@ -631,35 +622,20 @@ impl BuilderClient

{ eth_types::Block, ), Error, - > { - self.gen_inputs_with_anchor(block_num, false).await - } - - /// Perform all the steps to generate the circuit inputs - pub async fn gen_inputs_with_anchor( - &self, - block_num: u64, - has_anchor_tx: bool, - ) -> Result< - ( - CircuitInputBuilder, - eth_types::Block, - ), - Error, > { let (eth_block, geth_traces, history_hashes, prev_state_root) = self.get_block(block_num).await?; - let access_set = Self::get_state_accesses(ð_block, &geth_traces)?; + let access_set = + Self::get_state_accesses(ð_block, &geth_traces, &self.protocol_instance)?; let (proofs, codes) = self.get_state(block_num, access_set).await?; let (state_db, code_db) = Self::build_state_code_db(proofs, codes); - let builder = self.gen_inputs_from_state_with_anchor( + let builder = self.gen_inputs_from_state( state_db, code_db, ð_block, &geth_traces, history_hashes, prev_state_root, - has_anchor_tx, )?; Ok((builder, eth_block)) } diff --git a/bus-mapping/src/circuit_input_builder/block.rs b/bus-mapping/src/circuit_input_builder/block.rs index 650c7344bc..76958f9db8 100644 --- a/bus-mapping/src/circuit_input_builder/block.rs +++ b/bus-mapping/src/circuit_input_builder/block.rs @@ -2,12 +2,13 @@ use super::{ execution::ExecState, transaction::Transaction, CircuitsParams, CopyEvent, ExecStep, ExpEvent, + ProtocolInstance, }; use crate::{ operation::{OperationContainer, RWCounter}, Error, }; -use eth_types::{evm_unimplemented, Address, Word}; +use eth_types::{evm_unimplemented, Address, Hash, Word}; use std::collections::HashMap; /// Context of a [`Block`] which can mutate in a [`Transaction`]. @@ -68,8 +69,8 @@ pub struct Block { pub number: Word, /// difficulty pub timestamp: Word, - /// gas limit - pub difficulty: Word, + /// mix hash + pub mix_hash: Hash, /// base fee pub base_fee: Word, /// State root of the previous block @@ -90,6 +91,9 @@ pub struct Block { pub circuits_params: CircuitsParams, /// Original block from geth pub eth_block: eth_types::Block, + /// Protocol instance from protocol + /// If this is set, means we are in the taiko context + pub protocol_instance: Option, } impl Block { @@ -100,6 +104,7 @@ impl Block { prev_state_root: Word, eth_block: ð_types::Block, circuits_params: CircuitsParams, + protocol_instance: Option, ) -> Result { if eth_block.base_fee_per_gas.is_none() { // FIXME: resolve this once we have proper EIP-1559 support @@ -121,7 +126,9 @@ impl Block { .low_u64() .into(), timestamp: eth_block.timestamp, - difficulty: eth_block.difficulty, + mix_hash: eth_block + .mix_hash + .ok_or(Error::EthTypeError(eth_types::Error::IncompleteBlock))?, base_fee: eth_block.base_fee_per_gas.unwrap_or_default(), prev_state_root, container: OperationContainer::new(), @@ -141,6 +148,7 @@ impl Block { sha3_inputs: Vec::new(), circuits_params, eth_block: eth_block.clone(), + protocol_instance, }) } @@ -149,6 +157,11 @@ impl Block { &self.txs } + /// Check if in the taiko context. + pub fn is_taiko(&self) -> bool { + self.protocol_instance.is_some() + } + #[cfg(test)] pub fn txs_mut(&mut self) -> &mut Vec { &mut self.txs diff --git a/bus-mapping/src/circuit_input_builder/input_state_ref.rs b/bus-mapping/src/circuit_input_builder/input_state_ref.rs index 836a690ef7..5998ef67c5 100644 --- a/bus-mapping/src/circuit_input_builder/input_state_ref.rs +++ b/bus-mapping/src/circuit_input_builder/input_state_ref.rs @@ -43,6 +43,12 @@ pub struct CircuitInputStateRef<'a> { } impl<'a> CircuitInputStateRef<'a> { + /// Check if is a anchor transaction. + pub fn is_anchor_tx(&self) -> bool { + // set protocol_instance and is the first tx + self.block.is_taiko() && self.tx_ctx.is_first_tx() + } + /// Create a new step from a `GethExecStep` pub fn new_step(&self, geth_step: &GethExecStep) -> Result { let call_ctx = self.tx_ctx.call_ctx()?; @@ -309,10 +315,13 @@ impl<'a> CircuitInputStateRef<'a> { && (matches!(rw, RW::READ) || (op.value_prev.is_zero() && op.value.is_zero()))) && account.is_empty() { - panic!( - "RWTable Account field {:?} lookup to non-existing account rwc: {}, op: {:?}", - rw, self.block_ctx.rwc.0, op - ); + // FIXME: This is a temporary workaround for the above issue, which allows empty + // accounts to read for taiko's 1559 + + // panic!( + // "RWTable Account field {:?} lookup to non-existing account rwc: {}, op: {:?}", + // rw, self.block_ctx.rwc.0, op + // ); } // -- sanity check end -- // Perform the write to the account in the StateDB @@ -474,29 +483,21 @@ impl<'a> CircuitInputStateRef<'a> { must_create: bool, value: Word, fee: Option, - is_anchor_tx: bool, ) -> Result<(), Error> { let (found, sender_account) = self.sdb.get_account(&sender); if !found { return Err(Error::AccountNotFound(sender)); } let mut sender_balance_prev = sender_account.balance; - if !is_anchor_tx { - debug_assert!( - sender_account.balance >= value + fee.unwrap_or_default(), - "invalid amount balance {:?} value {:?} fee {:?}", - sender_balance_prev, - value, - fee - ); - } + debug_assert!( + sender_account.balance >= value + fee.unwrap_or_default(), + "invalid amount balance {:?} value {:?} fee {:?}", + sender_balance_prev, + value, + fee + ); if let Some(fee) = fee { - let sender_balance = if is_anchor_tx { - // anchor tx doesn't need fee - sender_balance_prev - } else { - sender_balance_prev - fee - }; + let sender_balance = sender_balance_prev - fee; log::trace!( "sender balance update with fee (not reversible): {:?} {:?}->{:?}", sender, @@ -583,7 +584,6 @@ impl<'a> CircuitInputStateRef<'a> { must_create, value, None, - false, ) } diff --git a/zkevm-circuits/src/witness/protocol_instance.rs b/bus-mapping/src/circuit_input_builder/protocol_instance.rs similarity index 71% rename from zkevm-circuits/src/witness/protocol_instance.rs rename to bus-mapping/src/circuit_input_builder/protocol_instance.rs index c2b385859b..b44aa4ad95 100644 --- a/zkevm-circuits/src/witness/protocol_instance.rs +++ b/bus-mapping/src/circuit_input_builder/protocol_instance.rs @@ -2,16 +2,18 @@ use std::iter; -use crate::{table::PiFieldTag, util::rlc_be_bytes}; -use eth_types::{Address, Bytes, Field, Hash, ToBigEndian, ToWord, Word, H256}; -use halo2_proofs::circuit::Value; +use eth_types::{Address, Bytes, Hash, ToBigEndian, ToWord, Word, H256}; use keccak256::plain::Keccak; +use mock::{ + MOCK_ANCHOR_GAS_LIMIT, MOCK_ANCHOR_L1_HASH, MOCK_ANCHOR_L1_HIGHT, MOCK_ANCHOR_PARENT_GAS_USED, + MOCK_ANCHOR_SIGNAL_ROOT, MOCK_TAIKO_L2_ADDRESS, MOCK_TAIKO_TREASURY_ADDRESS, +}; -// hash(anchor) -const ANCHOR_TX_METHOD_SIGNATURE: u32 = 0xda69d3db; +/// hash(anchor) +pub const ANCHOR_TX_METHOD_SIGNATURE: u32 = 0x3d384a4b; /// Taiko witness -#[derive(Debug, Default, Clone)] +#[derive(Debug, Clone)] pub struct ProtocolInstance { /// l1 signal service address pub l1_signal_service: Address, @@ -46,8 +48,35 @@ pub struct ProtocolInstance { pub anchor_gas_limit: u64, } +impl Default for ProtocolInstance { + fn default() -> Self { + Self { + anchor_gas_limit: MOCK_ANCHOR_GAS_LIMIT.as_u64(), + meta_hash: MetaHash { + l1_hash: *MOCK_ANCHOR_L1_HASH, + l1_height: *MOCK_ANCHOR_L1_HIGHT, + treasury: *MOCK_TAIKO_TREASURY_ADDRESS, + ..Default::default() + }, + signal_root: *MOCK_ANCHOR_SIGNAL_ROOT, + parent_gas_used: *MOCK_ANCHOR_PARENT_GAS_USED, + l1_signal_service: Address::default(), + l2_signal_service: Address::default(), + l2_contract: *MOCK_TAIKO_L2_ADDRESS, + block_hash: Hash::default(), + parent_hash: Hash::default(), + graffiti: H256::default(), + prover: Address::default(), + gas_used: 0, + block_max_gas_limit: 0, + max_transactions_per_block: 0, + max_bytes_per_tx_list: 0, + } + } +} + /// l1 meta hash -#[derive(Debug, Default, Clone)] +#[derive(Debug, Clone)] pub struct MetaHash { /// meta id pub id: u64, @@ -75,6 +104,25 @@ pub struct MetaHash { pub treasury: Address, } +impl Default for MetaHash { + fn default() -> Self { + Self { + id: 0, + timestamp: 0, + l1_height: 0, + l1_hash: Hash::default(), + l1_mix_hash: Hash::default(), + deposits_processed: Hash::default(), + tx_list_hash: Hash::default(), + tx_list_byte_start: 0, + tx_list_byte_end: 0, + gas_limit: 0, + beneficiary: Address::default(), + treasury: *MOCK_TAIKO_TREASURY_ADDRESS, + } + } +} + /// left shift x by n bits pub fn left_shift(x: T, n: u32) -> Word { assert!(n < 256); @@ -129,42 +177,6 @@ impl ProtocolInstance { result.extend_from_slice(&(self.parent_gas_used as u64).to_word().to_be_bytes()); result.into() } - - /// Assignments for pi table - pub fn table_assignments(&self, randomness: Value) -> [[Value; 2]; 6] { - [ - [ - Value::known(F::from(PiFieldTag::Null as u64)), - Value::known(F::ZERO), - ], - [ - Value::known(F::from(PiFieldTag::MethodSign as u64)), - Value::known(F::from(ANCHOR_TX_METHOD_SIGNATURE as u64)), - ], - [ - Value::known(F::from(PiFieldTag::L1Hash as u64)), - rlc_be_bytes(&self.meta_hash.l1_hash.to_fixed_bytes(), randomness), - ], - [ - Value::known(F::from(PiFieldTag::L1SignalRoot as u64)), - rlc_be_bytes(&self.signal_root.to_fixed_bytes(), randomness), - ], - [ - Value::known(F::from(PiFieldTag::L1Height as u64)), - rlc_be_bytes( - &self.meta_hash.l1_height.to_word().to_be_bytes(), - randomness, - ), - ], - [ - Value::known(F::from(PiFieldTag::ParentGasUsed as u64)), - rlc_be_bytes( - &(self.parent_gas_used as u64).to_word().to_be_bytes(), - randomness, - ), - ], - ] - } } #[cfg(test)] diff --git a/bus-mapping/src/circuit_input_builder/tracer_tests.rs b/bus-mapping/src/circuit_input_builder/tracer_tests.rs index 4ec5dcc209..8e631955bf 100644 --- a/bus-mapping/src/circuit_input_builder/tracer_tests.rs +++ b/bus-mapping/src/circuit_input_builder/tracer_tests.rs @@ -37,7 +37,7 @@ impl CircuitInputBuilderTx { let block = crate::mock::BlockData::new_from_geth_data(geth_data.clone()); let mut builder = block.new_circuit_input_builder(); let tx = builder - .new_tx(&block.eth_block.transactions[0], true) + .new_tx(&block.eth_block, &block.eth_block.transactions[0], true) .unwrap(); let tx_ctx = TransactionContext::new( &block.eth_block.transactions[0], @@ -48,7 +48,6 @@ impl CircuitInputBuilderTx { struct_logs: vec![geth_step.clone()], }, false, - false, ) .unwrap(); diff --git a/bus-mapping/src/circuit_input_builder/transaction.rs b/bus-mapping/src/circuit_input_builder/transaction.rs index 199603cf81..86461d2882 100644 --- a/bus-mapping/src/circuit_input_builder/transaction.rs +++ b/bus-mapping/src/circuit_input_builder/transaction.rs @@ -10,7 +10,7 @@ use crate::{ Error, }; -use super::{call::ReversionGroup, Call, CallContext, CallKind, CodeSource, ExecStep}; +use super::{call::ReversionGroup, Call, CallContext, CallKind, CodeSource, EthBlock, ExecStep}; #[derive(Debug, Default)] /// Context of a [`Transaction`] which can mutate in an [`ExecStep`]. @@ -19,7 +19,6 @@ pub struct TransactionContext { id: usize, /// The index of logs made in the transaction. pub(crate) log_id: usize, - is_anchor_tx: bool, /// Identifier if this transaction is last one of the block or not. is_last_tx: bool, /// Call stack. @@ -39,7 +38,6 @@ impl TransactionContext { pub fn new( eth_tx: ð_types::Transaction, geth_trace: &GethExecTrace, - is_anchor_tx: bool, is_last_tx: bool, ) -> Result { // Iterate over geth_trace to inspect and collect each call's is_success, which @@ -76,7 +74,6 @@ impl TransactionContext { .as_u64() as usize + 1, log_id: 0, - is_anchor_tx, is_last_tx, call_is_success, calls: Vec::new(), @@ -92,9 +89,9 @@ impl TransactionContext { self.id } - /// Return is_anchor_tx of the this transaction. - pub fn is_anchor_tx(&self) -> bool { - self.is_anchor_tx + /// Return true if it is the first transaction. + pub fn is_first_tx(&self) -> bool { + self.id == 1 } /// Return is_last_tx of the this transaction. @@ -201,8 +198,10 @@ impl Transaction { call_id: usize, sdb: &StateDB, code_db: &mut CodeDB, + eth_block: &EthBlock, eth_tx: ð_types::Transaction, is_success: bool, + is_taiko: bool, ) -> Result { let (found, _) = sdb.get_account(ð_tx.from); if !found { @@ -250,9 +249,21 @@ impl Transaction { ..Default::default() } }; + let mut tx: geth_types::Transaction = eth_tx.into(); + // reset gas_price + if eth_tx.transaction_index.unwrap_or_default() == 0.into() && is_taiko { + // anchor's gas_price is always 0 + tx.gas_price = 0.into(); + } else { + // gas_price = min(base_fee + gas_tip_cap, gas_fee_cap) + tx.gas_price = std::cmp::min( + eth_block.base_fee_per_gas.unwrap() + tx.gas_tip_cap, + tx.gas_fee_cap, + ); + } Ok(Self { - tx: eth_tx.into(), + tx, calls: vec![call], steps: Vec::new(), }) diff --git a/bus-mapping/src/evm/opcodes.rs b/bus-mapping/src/evm/opcodes.rs index 8efcf3d598..13f9c5c044 100644 --- a/bus-mapping/src/evm/opcodes.rs +++ b/bus-mapping/src/evm/opcodes.rs @@ -35,6 +35,7 @@ mod mload; mod mstore; mod number; mod origin; +mod push0; mod return_revert; mod returndatacopy; mod returndatasize; @@ -93,6 +94,7 @@ use logs::Log; use mload::Mload; use mstore::Mstore; use origin::Origin; +use push0::Push0; use return_revert::ReturnRevert; use returndatacopy::Returndatacopy; use returndatasize::Returndatasize; @@ -148,6 +150,9 @@ type FnGenAssociatedOps = fn( ) -> Result, Error>; fn fn_gen_associated_ops(opcode_id: &OpcodeId) -> FnGenAssociatedOps { + if opcode_id.is_push0() { + return Push0::gen_associated_ops; + } if opcode_id.is_push() { return StackOnlyOpcode::<0, 1>::gen_associated_ops; } diff --git a/bus-mapping/src/evm/opcodes/begin_end_tx.rs b/bus-mapping/src/evm/opcodes/begin_end_tx.rs index ba899d6ca0..a65e2561be 100644 --- a/bus-mapping/src/evm/opcodes/begin_end_tx.rs +++ b/bus-mapping/src/evm/opcodes/begin_end_tx.rs @@ -59,8 +59,8 @@ fn gen_begin_tx_steps(state: &mut CircuitInputStateRef) -> Result Result Result Result caller_balance_prev, )?; - let effective_tip = state.tx.tx.gas_price - state.block.base_fee; + let base_fee = if state.is_anchor_tx() { + 0.into() + } else { + state.block.base_fee + }; + + let effective_tip = state.tx.tx.gas_price - base_fee; let (found, coinbase_account) = state.sdb.get_account(&state.block.coinbase); if !found { return Err(Error::AccountNotFound(state.block.coinbase)); @@ -281,6 +294,32 @@ fn gen_end_tx_steps(state: &mut CircuitInputStateRef) -> Result coinbase_balance_prev, )?; + // transfer base fee to treasury account in taiko context + if state.block.is_taiko() { + let treasury = state + .block + .protocol_instance + .clone() + .unwrap() + .meta_hash + .treasury; + // add treasury account + let (found, treasury_account) = state.sdb.get_account(&treasury); + if !found { + return Err(Error::AccountNotFound(treasury)); + } + let treasury_balance_prev = treasury_account.balance; + let treasury_balance = + treasury_balance_prev + base_fee * (state.tx.gas() - exec_step.gas_left.0); + state.account_write( + &mut exec_step, + treasury, + AccountField::Balance, + treasury_balance, + treasury_balance_prev, + )?; + } + // handle tx receipt tag state.tx_receipt_write( &mut exec_step, diff --git a/bus-mapping/src/evm/opcodes/extcodesize.rs b/bus-mapping/src/evm/opcodes/extcodesize.rs index 440e6607e2..e8f526884a 100644 --- a/bus-mapping/src/evm/opcodes/extcodesize.rs +++ b/bus-mapping/src/evm/opcodes/extcodesize.rs @@ -97,7 +97,7 @@ mod extcodesize_tests { geth_types::{Account, GethData}, Bytecode, U256, }; - use mock::{TestContext, MOCK_1_ETH, MOCK_ACCOUNTS, MOCK_CODES}; + use mock::{TestContext, MOCK_1_ETH, MOCK_ACCOUNTS, MOCK_CODES, MOCK_COINBASE}; use pretty_assertions::assert_eq; #[test] @@ -151,7 +151,7 @@ mod extcodesize_tests { |mut txs, accs| { txs[0].to(accs[0].address).from(accs[2].address); }, - |block, _tx| block.number(0xcafeu64), + |block, _tx| block.author(*MOCK_COINBASE).number(0xcafeu64), ) .unwrap() .into(); diff --git a/bus-mapping/src/evm/opcodes/gasprice.rs b/bus-mapping/src/evm/opcodes/gasprice.rs index 44f0c60de4..c042372d76 100644 --- a/bus-mapping/src/evm/opcodes/gasprice.rs +++ b/bus-mapping/src/evm/opcodes/gasprice.rs @@ -95,7 +95,11 @@ mod gasprice_tests { (op_gasprice.rw(), op_gasprice.op()), ( RW::WRITE, - &StackOp::new(1, StackAddress(1023usize), two_gwei) + &StackOp::new( + 1, + StackAddress(1023usize), + builder.block.txs()[0].tx.gas_price + ) ) ); diff --git a/bus-mapping/src/evm/opcodes/push0.rs b/bus-mapping/src/evm/opcodes/push0.rs new file mode 100644 index 0000000000..eeffd7ec4f --- /dev/null +++ b/bus-mapping/src/evm/opcodes/push0.rs @@ -0,0 +1,27 @@ +use super::Opcode; +use crate::{ + circuit_input_builder::{CircuitInputStateRef, ExecStep}, + Error, +}; +use eth_types::{GethExecStep, U256}; + +#[derive(Clone, Copy, Debug)] +pub(crate) struct Push0; + +impl Opcode for Push0 { + 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)?; + + state.stack_write( + &mut exec_step, + geth_steps[1].stack.last_filled(), + U256::zero(), + )?; + + Ok(vec![exec_step]) + } +} diff --git a/bus-mapping/src/evm/opcodes/stackonlyop.rs b/bus-mapping/src/evm/opcodes/stackonlyop.rs index 21ec6bdcfe..dc609a6099 100644 --- a/bus-mapping/src/evm/opcodes/stackonlyop.rs +++ b/bus-mapping/src/evm/opcodes/stackonlyop.rs @@ -54,12 +54,12 @@ mod stackonlyop_tests { bytecode, evm_types::{OpcodeId, StackAddress}, geth_types::GethData, - word, Bytecode, Word, + word, Bytecode, ToWord, Word, }; use itertools::Itertools; use mock::{ test_ctx::{helpers::*, TestContext}, - MOCK_BASEFEE, MOCK_DIFFICULTY, MOCK_GASLIMIT, + MOCK_BASEFEE, MOCK_GASLIMIT, MOCK_MIX_HASH, }; use pretty_assertions::assert_eq; use std::ops::{BitOr, BitXor}; @@ -375,7 +375,7 @@ mod stackonlyop_tests { STOP }, vec![], - vec![StackOp::new(1, StackAddress(1023), *MOCK_DIFFICULTY)], + vec![StackOp::new(1, StackAddress(1023), MOCK_MIX_HASH.to_word())], ); } diff --git a/bus-mapping/src/mock.rs b/bus-mapping/src/mock.rs index 57ecae2475..facd8ff2ac 100644 --- a/bus-mapping/src/mock.rs +++ b/bus-mapping/src/mock.rs @@ -40,6 +40,7 @@ impl BlockData { Word::default(), &self.eth_block, self.circuits_params, + None, ) .unwrap(), ) @@ -52,7 +53,7 @@ impl BlockData { let mut sdb = StateDB::new(); let mut code_db = CodeDB::new(); - let access_set = get_state_accesses(&geth_data.eth_block, &geth_data.geth_traces) + let access_set = get_state_accesses(&geth_data.eth_block, &geth_data.geth_traces, &None) .expect("state accesses"); // Initialize all accesses accounts to zero for addr in access_set.state.keys() { diff --git a/circuit-benchmarks/src/taiko_super_circuit.rs b/circuit-benchmarks/src/taiko_super_circuit.rs index 01edd78985..2b3ec07205 100644 --- a/circuit-benchmarks/src/taiko_super_circuit.rs +++ b/circuit-benchmarks/src/taiko_super_circuit.rs @@ -9,10 +9,9 @@ use zkevm_circuits::{ taiko_aggregation::AccumulationSchemeType, KzgDk, KzgSvk, TaikoAggregationCircuit, }, taiko_super_circuit::{test::block_1tx, SuperCircuit}, - witness::ProtocolInstance, }; -use bus_mapping::circuit_input_builder::CircuitsParams; +use bus_mapping::circuit_input_builder::{CircuitsParams, ProtocolInstance}; use rand::SeedableRng; @@ -43,6 +42,9 @@ use snark_verifier::{ verifier::SnarkVerifier, }; +const MIN_APP_DEGREE: u32 = 18; +const MIN_AGG_DEGREE: u32 = 24; + /// Number of limbs to decompose a elliptic curve base field element into. pub const LIMBS: usize = 4; /// Number of bits of each decomposed limb. @@ -159,16 +161,9 @@ fn gen_application_snark( max_evm_rows: 0, max_keccak_rows: 0, }; - let protocol_instance = ProtocolInstance { - anchor_gas_limit: 150000, - ..Default::default() - }; - let (_, super_circuit, _, _) = SuperCircuit::<_>::build( - block_1tx(&protocol_instance), - circuits_params, - protocol_instance, - ) - .unwrap(); + let protocol_instance = ProtocolInstance::default(); + let (_, super_circuit, _, _) = + SuperCircuit::<_>::build(block_1tx(), circuits_params, protocol_instance).unwrap(); // let pk = gen_pk(params, &super_circuit, Some(Path::new("./examples/app.pk")), // super_circuit.params()); @@ -183,11 +178,11 @@ fn gen_application_snark( } fn create_root_super_circuit_prover_sdk() { - let params_app = gen_srs(18); + let params_app = gen_srs(MIN_APP_DEGREE); let aggregation_type = T.into(); let snarks = [(); 1].map(|_| gen_application_snark(¶ms_app, aggregation_type)); - let params = gen_srs(22); + let params = gen_srs(MIN_AGG_DEGREE); let mut snark_roots = Vec::new(); for snark in snarks { let pcd_circuit = TaikoAggregationCircuit::::new(¶ms, [snark]).unwrap(); @@ -228,7 +223,7 @@ fn create_root_super_circuit_prover_sdk } println!("gen blocks agg snark"); - let params = gen_srs(22); + let params = gen_srs(MIN_AGG_DEGREE); let agg_circuit = TaikoAggregationCircuit::::new(¶ms, snark_roots).unwrap(); println!("new root agg circuit {}", agg_circuit); @@ -289,14 +284,12 @@ fn create_root_super_circuit_prover_sdk // for N super circuit -> 1 root circuit integration fn create_1_level_root_super_circuit_prover_sdk() { let agg_type = T.into(); - let app_degree = 18; - let min_k_aggretation = 22; - let mut params_app = gen_srs(min_k_aggretation); - params_app.downsize(app_degree); + let mut params_app = gen_srs(MIN_AGG_DEGREE); + params_app.downsize(MIN_APP_DEGREE); let snarks = [(); 1].map(|_| gen_application_snark(¶ms_app, agg_type)); println!("gen blocks agg snark"); - let params = gen_srs(min_k_aggretation); + let params = gen_srs(MIN_AGG_DEGREE); let agg_circuit = TaikoAggregationCircuit::::new(¶ms, snarks).unwrap(); let start0 = start_timer!(|| "gen vk & pk"); // let pk = gen_pk( diff --git a/eth-types/src/evm_types.rs b/eth-types/src/evm_types.rs index 61d1441892..efba45f118 100644 --- a/eth-types/src/evm_types.rs +++ b/eth-types/src/evm_types.rs @@ -72,6 +72,8 @@ impl From for u64 { } } +/// Once per word of the init code when creating a contract. +pub const INIT_CODE_WORD_GAS: u64 = 2; /// Quotient for max refund of gas used pub const MAX_REFUND_QUOTIENT_OF_GAS_USED: usize = 5; /// Gas stipend when CALL or CALLCODE is attached with value. diff --git a/eth-types/src/evm_types/opcode_ids.rs b/eth-types/src/evm_types/opcode_ids.rs index d9192fcae4..db6a96d26d 100644 --- a/eth-types/src/evm_types/opcode_ids.rs +++ b/eth-types/src/evm_types/opcode_ids.rs @@ -95,6 +95,8 @@ pub enum OpcodeId { JUMPDEST, // PUSHn + /// `PUSH0` + PUSH0, /// `PUSH1` PUSH1, /// `PUSH2` @@ -320,6 +322,11 @@ impl OpcodeId { self.as_u8() >= Self::PUSH1.as_u8() && self.as_u8() <= Self::PUSH32.as_u8() } + /// Returns `true` if the `OpcodeId` is a `PUSH0`. + pub fn is_push0(&self) -> bool { + self == &Self::PUSH0 + } + /// Returns `true` if the `OpcodeId` is a `DUPn`. pub fn is_dup(&self) -> bool { self.as_u8() >= Self::DUP1.as_u8() && self.as_u8() <= Self::DUP16.as_u8() @@ -402,6 +409,7 @@ impl OpcodeId { OpcodeId::PC => 0x58u8, OpcodeId::MSIZE => 0x59u8, OpcodeId::JUMPDEST => 0x5bu8, + OpcodeId::PUSH0 => 0x5fu8, OpcodeId::PUSH1 => 0x60u8, OpcodeId::PUSH2 => 0x61u8, OpcodeId::PUSH3 => 0x62u8, @@ -580,6 +588,7 @@ impl OpcodeId { OpcodeId::MSIZE => GasCost::QUICK, OpcodeId::GAS => GasCost::QUICK, OpcodeId::JUMPDEST => GasCost::ONE, + OpcodeId::PUSH0 => GasCost::QUICK, OpcodeId::PUSH1 => GasCost::FASTEST, OpcodeId::PUSH2 => GasCost::FASTEST, OpcodeId::PUSH3 => GasCost::FASTEST, @@ -734,6 +743,7 @@ impl OpcodeId { OpcodeId::MSIZE => (1, 1024), OpcodeId::GAS => (1, 1024), OpcodeId::JUMPDEST => (0, 1024), + OpcodeId::PUSH0 => (1, 1024), OpcodeId::PUSH1 => (1, 1024), OpcodeId::PUSH2 => (1, 1024), OpcodeId::PUSH3 => (1, 1024), @@ -936,6 +946,7 @@ impl From for OpcodeId { 0x58u8 => OpcodeId::PC, 0x59u8 => OpcodeId::MSIZE, 0x5bu8 => OpcodeId::JUMPDEST, + 0x5fu8 => OpcodeId::PUSH0, 0x60u8 => OpcodeId::PUSH1, 0x61u8 => OpcodeId::PUSH2, 0x62u8 => OpcodeId::PUSH3, @@ -1089,6 +1100,7 @@ impl FromStr for OpcodeId { "PC" => OpcodeId::PC, "MSIZE" => OpcodeId::MSIZE, "JUMPDEST" => OpcodeId::JUMPDEST, + "PUSH0" => OpcodeId::PUSH0, "PUSH1" => OpcodeId::PUSH1, "PUSH2" => OpcodeId::PUSH2, "PUSH3" => OpcodeId::PUSH3, @@ -1156,7 +1168,6 @@ impl FromStr for OpcodeId { "RETURN" => OpcodeId::RETURN, "REVERT" => OpcodeId::REVERT, "INVALID" => OpcodeId::INVALID(0xfe), - "PUSH0" => OpcodeId::INVALID(0x5f), "SHA3" | "KECCAK256" => OpcodeId::SHA3, "ADDRESS" => OpcodeId::ADDRESS, "BALANCE" => OpcodeId::BALANCE, diff --git a/eth-types/src/geth_types.rs b/eth-types/src/geth_types.rs index e34111de4b..7f6151514b 100644 --- a/eth-types/src/geth_types.rs +++ b/eth-types/src/geth_types.rs @@ -6,7 +6,10 @@ use crate::{ ToWord, Word, U64, }; use ethers_core::{ - types::{transaction::response, NameOrAddress, TransactionRequest}, + types::{ + transaction::{eip2718::TypedTransaction, response}, + Eip1559TransactionRequest, NameOrAddress, + }, utils::get_contract_address, }; use ethers_signers::{LocalWallet, Signer}; @@ -69,7 +72,7 @@ pub struct BlockConstants { /// U64 type is required to serialize into proper hex with 0x prefix pub number: U64, /// difficulty - pub difficulty: Word, + pub mix_hash: Hash, /// gas limit pub gas_limit: Word, /// base fee @@ -84,7 +87,7 @@ impl TryFrom<&Block> for BlockConstants { coinbase: block.author.ok_or(Error::IncompleteBlock)?, timestamp: block.timestamp, number: block.number.ok_or(Error::IncompleteBlock)?, - difficulty: block.difficulty, + mix_hash: block.mix_hash.ok_or(Error::IncompleteBlock)?, gas_limit: block.gas_limit, base_fee: block.base_fee_per_gas.ok_or(Error::IncompleteBlock)?, }) @@ -97,7 +100,7 @@ impl BlockConstants { coinbase: Address, timestamp: Word, number: U64, - difficulty: Word, + mix_hash: Hash, gas_limit: Word, base_fee: Word, ) -> BlockConstants { @@ -105,7 +108,7 @@ impl BlockConstants { coinbase, timestamp, number, - difficulty, + mix_hash, gas_limit, base_fee, } @@ -158,8 +161,8 @@ impl From<&Transaction> for crate::Transaction { gas: tx.gas_limit.to_word(), value: tx.value, gas_price: Some(tx.gas_price), - max_priority_fee_per_gas: Some(tx.gas_fee_cap), - max_fee_per_gas: Some(tx.gas_tip_cap), + max_priority_fee_per_gas: Some(tx.gas_tip_cap), + max_fee_per_gas: Some(tx.gas_fee_cap), input: tx.call_data.clone(), access_list: tx.access_list.clone(), v: tx.v.into(), @@ -179,8 +182,8 @@ impl From<&crate::Transaction> for Transaction { gas_limit: tx.gas.as_u64().into(), value: tx.value, gas_price: tx.gas_price.unwrap_or_default(), - gas_fee_cap: tx.max_priority_fee_per_gas.unwrap_or_default(), - gas_tip_cap: tx.max_fee_per_gas.unwrap_or_default(), + gas_tip_cap: tx.max_priority_fee_per_gas.unwrap_or_default(), + gas_fee_cap: tx.max_fee_per_gas.unwrap_or_default(), call_data: tx.input.clone(), access_list: tx.access_list.clone(), v: tx.v.as_u64(), @@ -190,13 +193,14 @@ impl From<&crate::Transaction> for Transaction { } } -impl From<&Transaction> for TransactionRequest { - fn from(tx: &Transaction) -> TransactionRequest { - TransactionRequest { +impl From<&Transaction> for Eip1559TransactionRequest { + fn from(tx: &Transaction) -> Eip1559TransactionRequest { + Eip1559TransactionRequest { from: Some(tx.from), to: tx.to.map(NameOrAddress::Address), gas: Some(tx.gas_limit.to_word()), - gas_price: Some(tx.gas_price), + max_priority_fee_per_gas: Some(tx.gas_tip_cap), + max_fee_per_gas: Some(tx.gas_fee_cap), value: Some(tx.value), data: Some(tx.call_data.clone()), nonce: Some(tx.nonce.to_word()), @@ -229,9 +233,13 @@ impl Transaction { secp256k1::Fq::from_repr(sig_s_le), Error::Signature(libsecp256k1::Error::InvalidSignature), )?; - // msg = rlp([nonce, gasPrice, gas, to, value, data, sig_v, r, s]) - let req: TransactionRequest = self.into(); - let msg = req.chain_id(chain_id).rlp(); + // msg = rlp([chainId, nonce, maxPriorityFeePerGas, maxFeePerGas, gas, to, value, data, + // accessList]) + let req: Eip1559TransactionRequest = self.into(); + let req = req.chain_id(chain_id); + // insert 0x2 at the begin of rlp + let req: TypedTransaction = req.into(); + let msg = req.rlp(); let msg_hash: [u8; 32] = Keccak256::digest(&msg) .as_slice() .to_vec() @@ -325,7 +333,7 @@ impl GethData { let wallet = wallets.get(&tx.from).unwrap(); assert_eq!(Word::from(wallet.chain_id()), self.chain_id); let geth_tx: Transaction = (&*tx).into(); - let req: TransactionRequest = (&geth_tx).into(); + let req: Eip1559TransactionRequest = (&geth_tx).into(); let sig = wallet.sign_transaction_sync(&req.chain_id(self.chain_id.as_u64()).into()); tx.v = U64::from(sig.v); tx.r = sig.r; diff --git a/eth-types/src/lib.rs b/eth-types/src/lib.rs index e3417d6e50..f2e23e7345 100644 --- a/eth-types/src/lib.rs +++ b/eth-types/src/lib.rs @@ -723,7 +723,7 @@ mod eth_types_test { ..Default::default() }; - let req: ethers_core::types::TransactionRequest = tx.into(); + let req: ethers_core::types::Eip1559TransactionRequest = tx.into(); assert_eq!(req.to, None); Ok(()) } diff --git a/external-tracer/src/lib.rs b/external-tracer/src/lib.rs index 678bc21e33..539777bda3 100644 --- a/external-tracer/src/lib.rs +++ b/external-tracer/src/lib.rs @@ -23,22 +23,21 @@ pub struct TraceConfig { pub transactions: Vec, /// logger pub logger_config: LoggerConfig, + /// taiko + pub taiko: bool, } /// Configuration structure for `logger.Config` #[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "PascalCase")] pub struct LoggerConfig { /// enable memory capture - #[serde(rename = "EnableMemory")] pub enable_memory: bool, /// disable stack capture - #[serde(rename = "DisableStack")] pub disable_stack: bool, /// disable storage capture - #[serde(rename = "DisableStorage")] pub disable_storage: bool, /// enable return data capture - #[serde(rename = "EnableReturnData")] pub enable_return_data: bool, } diff --git a/geth-utils/gethutil/asm.go b/geth-utils/gethutil/asm.go index b5546f876a..2a874c22bd 100644 --- a/geth-utils/gethutil/asm.go +++ b/geth-utils/gethutil/asm.go @@ -37,7 +37,7 @@ func (a *Asm) PrintMnemonics(out io.Writer) { for idx := 0; idx < len(a.bytecode); { code := vm.OpCode(a.bytecode[idx]) if code.IsPush() { - n := int(code) - int(vm.PUSH1) + 1 + n := int(code) - int(vm.PUSH0) fmt.Fprintf(out, "%02d\t%s\t0x%x\n", idx, code.String(), a.bytecode[idx+1:idx+1+n]) idx += n + 1 } else { @@ -121,6 +121,8 @@ func (a *Asm) MSize() *Asm { return a.appendByte(vm.MSIZE) } func (a *Asm) Gas() *Asm { return a.appendByte(vm.GAS) } func (a *Asm) JumpDest(label ...string) *Asm { return a.jumpDest(label...) } +func (a *Asm) Push0() *Asm { return a.appendByte(vm.PUSH0) } + // 0x60 range func (a *Asm) PushX(val interface{}) *Asm { return a.push(val) } func (a *Asm) DupX(x int) *Asm { @@ -200,7 +202,7 @@ func (a *Asm) push(v ...interface{}) *Asm { bytes := toBytes(v) rangeCheck(len(bytes), 1, 32, "len(bytes)") - a.appendByte(int(vm.PUSH1) + len(bytes) - 1) + a.appendByte(int(vm.PUSH0) + len(bytes)) for _, b := range bytes { a.appendByte(b) diff --git a/geth-utils/gethutil/trace.go b/geth-utils/gethutil/trace.go index 744ce01d40..5aa6f89bb6 100644 --- a/geth-utils/gethutil/trace.go +++ b/geth-utils/gethutil/trace.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" @@ -82,12 +83,12 @@ func FormatLogs(logs []logger.StructLog) []StructLogRes { } type Block struct { - Coinbase common.Address `json:"coinbase"` - Timestamp *hexutil.Big `json:"timestamp"` - Number *hexutil.Big `json:"number"` - Difficulty *hexutil.Big `json:"difficulty"` - GasLimit *hexutil.Big `json:"gas_limit"` - BaseFee *hexutil.Big `json:"base_fee"` + Coinbase common.Address `json:"coinbase"` + Timestamp *hexutil.Big `json:"timestamp"` + Number *hexutil.Big `json:"number"` + GasLimit *hexutil.Big `json:"gas_limit"` + BaseFee *hexutil.Big `json:"base_fee"` + MixHash common.Hash `json:"mix_hash"` } type Account struct { @@ -122,56 +123,61 @@ type TraceConfig struct { Accounts map[common.Address]Account `json:"accounts"` Transactions []Transaction `json:"transactions"` LoggerConfig *logger.Config `json:"logger_config"` + Taiko bool `json:"taiko"` } func newUint64(val uint64) *uint64 { return &val } func Trace(config TraceConfig) ([]*ExecutionResult, error) { chainConfig := params.ChainConfig{ - ChainID: toBigInt(config.ChainID), - HomesteadBlock: big.NewInt(0), - DAOForkBlock: big.NewInt(0), - DAOForkSupport: true, - EIP150Block: big.NewInt(0), - EIP150Hash: common.Hash{}, - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), + ChainID: toBigInt(config.ChainID), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: big.NewInt(0), + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ShanghaiTime: newUint64(0), + MergeNetsplitBlock: nil, + TerminalTotalDifficulty: common.Big0, + TerminalTotalDifficultyPassed: true, + Taiko: config.Taiko, } var txsGasLimit uint64 blockGasLimit := toBigInt(config.Block.GasLimit).Uint64() messages := make([]core.Message, len(config.Transactions)) for i, tx := range config.Transactions { - // If gas price is specified directly, the tx is treated as legacy type. - if tx.GasPrice != nil { - tx.GasFeeCap = tx.GasPrice - tx.GasTipCap = tx.GasPrice - } + // only support EIP-1559 txs + gasPrice := math.BigMin(new(big.Int).Add(toBigInt(tx.GasTipCap), toBigInt(config.Block.BaseFee)), toBigInt(tx.GasFeeCap)) txAccessList := make(types.AccessList, len(tx.AccessList)) for i, accessList := range tx.AccessList { txAccessList[i].Address = accessList.Address txAccessList[i].StorageKeys = accessList.StorageKeys } + messages[i] = core.Message{ - From: tx.From, - To: tx.To, - Nonce: uint64(tx.Nonce), - Value: toBigInt(tx.Value), - GasLimit: uint64(tx.GasLimit), - GasPrice: toBigInt(tx.GasPrice), - GasFeeCap: toBigInt(tx.GasFeeCap), - GasTipCap: toBigInt(tx.GasTipCap), - Data: tx.CallData, - AccessList: txAccessList, + From: tx.From, + To: tx.To, + Nonce: uint64(tx.Nonce), + Value: toBigInt(tx.Value), + GasLimit: uint64(tx.GasLimit), + GasPrice: gasPrice, + GasFeeCap: toBigInt(tx.GasFeeCap), + GasTipCap: toBigInt(tx.GasTipCap), + Data: tx.CallData, + AccessList: txAccessList, SkipAccountChecks: false, + // treat the first tx as anchor tx when Taiko is enabled + IsAnchor: config.Taiko && i == 0, } txsGasLimit += uint64(tx.GasLimit) @@ -194,9 +200,9 @@ func Trace(config TraceConfig) ([]*ExecutionResult, error) { Coinbase: config.Block.Coinbase, BlockNumber: toBigInt(config.Block.Number), Time: toBigInt(config.Block.Timestamp).Uint64(), - Difficulty: toBigInt(config.Block.Difficulty), BaseFee: toBigInt(config.Block.BaseFee), GasLimit: blockGasLimit, + Random: &config.Block.MixHash, } // Setup state db with accounts from argument @@ -217,7 +223,7 @@ func Trace(config TraceConfig) ([]*ExecutionResult, error) { executionResults := make([]*ExecutionResult, len(config.Transactions)) for i, message := range messages { tracer := logger.NewStructLogger(config.LoggerConfig) - evm := vm.NewEVM(blockCtx, core.NewEVMTxContext(&message), stateDB, &chainConfig, vm.Config{Debug: true, Tracer: tracer, NoBaseFee: true}) + evm := vm.NewEVM(blockCtx, core.NewEVMTxContext(&message), stateDB, &chainConfig, vm.Config{Tracer: tracer, NoBaseFee: true}) result, err := core.ApplyMessage(evm, &message, new(core.GasPool).AddGas(message.GasLimit)) if err != nil { diff --git a/geth-utils/go.mod b/geth-utils/go.mod index 2892aa855f..6551098ca8 100644 --- a/geth-utils/go.mod +++ b/geth-utils/go.mod @@ -3,9 +3,10 @@ module main go 1.16 require ( - github.com/ethereum/go-ethereum v1.11.5 - github.com/holiman/uint256 v1.2.0 + github.com/ethereum/go-ethereum v1.12.2 + github.com/holiman/uint256 v1.2.3 ) // Uncomment for debugging // replace github.com/ethereum/go-ethereum => ../../go-ethereum +replace github.com/ethereum/go-ethereum v1.12.2 => github.com/taikoxyz/taiko-geth v0.0.0-20230814083522-76b7e96ec36f diff --git a/geth-utils/go.sum b/geth-utils/go.sum index 62c668a662..7aaa4478b0 100644 --- a/geth-utils/go.sum +++ b/geth-utils/go.sum @@ -49,6 +49,7 @@ github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= @@ -102,6 +103,9 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bits-and-blooms/bitset v1.5.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo= +github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c= @@ -121,8 +125,11 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927/go.mod h1:h/aW8ynjgkuj+NQRlZcDbAbM1ORAbXjXX77sX7T289U= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -147,9 +154,11 @@ github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= -github.com/consensys/gnark-crypto v0.9.1-0.20230105202408-1a7a29904a7c/go.mod h1:CkbdF9hbRidRJYMRzmfX8TMOr95I2pYXRHF18MzRrvA= +github.com/consensys/gnark-crypto v0.10.0 h1:zRh22SR7o4K35SoNqouS9J/TKHTyU2QWaj5ldehyXtA= +github.com/consensys/gnark-crypto v0.10.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= @@ -162,7 +171,9 @@ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwc github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-ipa v0.0.0-20220523130400-f11357ae11c7/go.mod h1:gFnFS95y8HstDP6P9pPwzrxOOC5TRDkwbM+ao15ChAI= +github.com/crate-crypto/go-ipa v0.0.0-20230601170251-1830d0757c80/go.mod h1:gzbVz57IDJgQ9rLQwfSk696JGWof8ftznEL9GoAv3NI= +github.com/crate-crypto/go-kzg-4844 v0.3.0 h1:UBlWE0CgyFqqzTI+IFyCzA7A3Zw4iip6uzRv5NIXG0A= +github.com/crate-crypto/go-kzg-4844 v0.3.0/go.mod h1:SBP7ikXEgDnUPONgm33HtuDZEDtWa3L4QtN1ocJSEQ4= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= @@ -195,12 +206,11 @@ github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5O github.com/docker/docker v1.6.2/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/dop251/goja v0.0.0-20211022113120-dc8c55024d06/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= -github.com/dop251/goja v0.0.0-20230122112309-96b1610dd4f7/go.mod h1:yRkwfj0CBpOGre+TwBsqPV0IH0Pk73e4PXJOeNDboGs= +github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3/go.mod h1:QMWlm50DNe14hD7t24KEqZuUdC9sOTy8W6XbCU1mlw4= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= -github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -211,13 +221,14 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= +github.com/ethereum/c-kzg-4844 v0.3.1 h1:sR65+68+WdnMKxseNWxSJuAv2tsUrihTpVBTfM/U5Zg= +github.com/ethereum/c-kzg-4844 v0.3.1/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= -github.com/ethereum/go-ethereum v1.11.5 h1:3M1uan+LAUvdn+7wCEFrcMM4LJTeuxDrPTg/f31a5QQ= -github.com/ethereum/go-ethereum v1.11.5/go.mod h1:it7x0DWnTDMfVFdXcU6Ti4KEFQynLHVRarcSlPr0HBo= github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= +github.com/fjl/gencodec v0.0.0-20230517082657-f9840df7b83e/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= github.com/flosch/pongo2/v4 v4.0.2/go.mod h1:B5ObFANs/36VwxxlgKpdchIJHMvHB562PW+BWPhwZD8= @@ -230,7 +241,7 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/gballet/go-verkle v0.0.0-20220902153445-097bd83b7732/go.mod h1:o/XfIXWi4/GqbQirfRm5uTbXMG5NpqxkxblnbZ+QM9I= +github.com/gballet/go-verkle v0.0.0-20230607174250-df487255f46b/go.mod h1:CDncRYVRSDqwakm282WEkjfaAj1hxU/v5RXxk5nXOiI= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= @@ -337,8 +348,9 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -378,6 +390,7 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -423,10 +436,12 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/holiman/billy v0.0.0-20230718173358-1c7e68d277a7/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= +github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= +github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= @@ -434,11 +449,13 @@ github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:q github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= +github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= @@ -481,6 +498,7 @@ github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= +github.com/karalabe/usb v0.0.3-0.20230711191512-61db3e06439c/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kataras/blocks v0.0.6/go.mod h1:UK+Iwk0Oxpc0GdoJja7sEildotAUKK1LYeYcVF0COWc= github.com/kataras/blocks v0.0.7/go.mod h1:UJIU97CluDo0f+zEjbnbkeMRlvYORtmc1304EeyXf4I= github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= @@ -500,6 +518,7 @@ github.com/kataras/pio v0.0.11/go.mod h1:38hH6SWH6m4DKSYmRhlrCJ5WItwWgCVrTNU62XZ github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kataras/sitemap v0.0.6/go.mod h1:dW4dOCNs896OR1HmG+dMLdT7JjDk7mYBzoIRwuj5jA4= github.com/kataras/tunnel v0.0.4/go.mod h1:9FkU4LaeifdMWqZu7o20ojmW4B7hdhv2CMLwfnHGpYw= +github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -541,6 +560,7 @@ github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awS github.com/labstack/echo/v4 v4.9.0/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -597,6 +617,7 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -672,6 +693,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= @@ -708,6 +730,7 @@ github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0ua github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/protolambda/bls12-381-util v0.0.0-20220416220906-d8552aa452c7/go.mod h1:IToEjHuttnUzwZI5KBSM/LOOW3qLbbrHOEfp3SbECGY= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= @@ -773,6 +796,7 @@ github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -783,12 +807,17 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= +github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/taikoxyz/taiko-geth v0.0.0-20230814083522-76b7e96ec36f h1:tbDbbWKensnOvnKyMdSScFOj0bZSjeUUmte/gmOEMm8= +github.com/taikoxyz/taiko-geth v0.0.0-20230814083522-76b7e96ec36f/go.mod h1:1cRAEV+rp/xX0zraSCBnu9Py3HQ+geRMj3HdR+k0wfI= github.com/tdewolff/minify/v2 v2.12.1/go.mod h1:p5pwbvNs1ghbFED/ZW1towGsnnWwzvM8iz8l0eURi9g= github.com/tdewolff/minify/v2 v2.12.4/go.mod h1:h+SRvSIX3kwgwTFOpSckvSxgax3uy8kZTSF1Ojrr3bk= github.com/tdewolff/parse/v2 v2.6.3/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs= @@ -812,7 +841,7 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa/go.mod h1:1CNUng3PtjQMtRzJO4FMXBQvkGtuYRxxiR9xMa7jMwI= +github.com/urfave/cli/v2 v2.24.1/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= @@ -859,6 +888,7 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= @@ -889,8 +919,9 @@ golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -906,8 +937,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20220426173459-3bcf042a4bf5/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= -golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg= -golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230810033253-352e893a4cad h1:g0bG7Z4uG+OgH2QDODnjp6ggkk1bJDsINcuWmJN1iJU= +golang.org/x/exp v0.0.0-20230810033253-352e893a4cad/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -938,6 +969,9 @@ golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20211013180041-c96bc1413d57/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1002,8 +1036,10 @@ golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfS golang.org/x/net v0.0.0-20221002022538-bcab6841153b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1032,8 +1068,10 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1087,6 +1125,7 @@ golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1121,8 +1160,8 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1134,13 +1173,18 @@ golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1150,10 +1194,12 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1162,6 +1208,7 @@ golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1227,6 +1274,8 @@ golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8-0.20211029000441-d6a9af8af023/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1367,6 +1416,7 @@ gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= @@ -1400,4 +1450,5 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/geth-utils/src/lib.rs b/geth-utils/src/lib.rs index 60a237164f..66f1539306 100644 --- a/geth-utils/src/lib.rs +++ b/geth-utils/src/lib.rs @@ -97,7 +97,8 @@ mod test { "from": "0x00000000000000000000000000000000000000fe", "to": "0x00000000000000000000000000000000000000ff", "gas_limit": "0x5208", - "gas_price": "0x77359400" + "gas_tip_cap": "0x77359400", + "gas_fee_cap": "0x77359400" } ] }"#, @@ -131,7 +132,8 @@ mod test { "from": "0x00000000000000000000000000000000000000fe", "to": "0x00000000000000000000000000000000000000ff", "gas_limit": "0x5208", - "gas_price": "0x1111" + "gas_tip_cap": "0x1111", + "gas_fee_cap": "0x1111" } ] }"#, diff --git a/integration-tests/src/integration_test_circuits.rs b/integration-tests/src/integration_test_circuits.rs index 93ea7d1540..9d55758fbe 100644 --- a/integration-tests/src/integration_test_circuits.rs +++ b/integration-tests/src/integration_test_circuits.rs @@ -334,7 +334,9 @@ async fn gen_inputs( eth_types::Block, ) { let cli = get_client(); - let cli = BuilderClient::new(cli, CIRCUITS_PARAMS).await.unwrap(); + let cli = BuilderClient::new(cli, CIRCUITS_PARAMS, Default::default()) + .await + .unwrap(); cli.gen_inputs(block_num).await.unwrap() } diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index 673c2ad2fa..80feb38fa4 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -163,6 +163,7 @@ pub async fn build_circuit_input_builder_block(block_num: u64) { max_exp_steps: 1000, max_keccak_rows: 0, }, + Default::default(), ) .await .unwrap(); @@ -172,7 +173,7 @@ pub async fn build_circuit_input_builder_block(block_num: u64) { cli.get_block(block_num).await.unwrap(); // 2. Get State Accesses from TxExecTraces - let access_set = get_state_accesses(ð_block, &geth_trace).unwrap(); + let access_set = get_state_accesses(ð_block, &geth_trace, &None).unwrap(); trace!("AccessSet: {:#?}", access_set); // 3. Query geth for all accounts, storage keys, and codes from Accesses diff --git a/mock/Cargo.toml b/mock/Cargo.toml index b8396f703e..ce768641c0 100644 --- a/mock/Cargo.toml +++ b/mock/Cargo.toml @@ -6,6 +6,9 @@ authors = ["The appliedzkp team"] license = "MIT OR Apache-2.0" [dependencies] +halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.git", features = [ + "circuit-params", +], tag = "v2023_04_20" } eth-types = { path = "../eth-types" } external-tracer = { path = "../external-tracer" } lazy_static = "1.4" @@ -14,3 +17,8 @@ ethers-signers = "=2.0.0" ethers-core = "=2.0.0" rand_chacha = "0.3" rand = "0.8" +sha3 = "0.10" +num-bigint = { version = "0.4" } +num = "0.4" +libsecp256k1 = "0.7" +once_cell = "1.17.1" diff --git a/mock/src/anchor.rs b/mock/src/anchor.rs new file mode 100644 index 0000000000..138be37d76 --- /dev/null +++ b/mock/src/anchor.rs @@ -0,0 +1,103 @@ +use crate::{ + MockTransaction, GOLDEN_TOUCH_PRIVATEKEY, MOCK_ANCHOR_L1_HASH, MOCK_ANCHOR_L1_HIGHT, + MOCK_ANCHOR_PARENT_GAS_USED, MOCK_ANCHOR_SIGNAL_ROOT, MOCK_CHAIN_ID, +}; +use eth_types::{ + geth_types::Transaction, + sign_types::{biguint_to_32bytes_le, ct_option_ok_or, sign as eth_sign, SignData, SECP256K1_Q}, + word, Bytes, ToBigEndian, ToLittleEndian, ToWord, Word, U256, +}; +use ethers_core::types::{transaction::eip2718::TypedTransaction, Eip1559TransactionRequest}; +use halo2_proofs::{ + arithmetic::Field as _, + halo2curves::{ + ff::PrimeField, + group::Curve, + secp256k1::{self, Secp256k1Affine}, + }, +}; +use num::Integer; +use num_bigint::BigUint; +use once_cell::sync::Lazy; +use sha3::{Digest, Keccak256}; + +static GX1: Lazy = + Lazy::new(|| word!("0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798")); +static GX2: Lazy = + Lazy::new(|| word!("0xc6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5")); + +fn fixd_k_sign(anchor_tx: &Transaction, chain_id: u64) -> Result { + // msg = rlp([nonce, gasPrice, gas, to, value, data, sig_v, r, s]) + let req: Eip1559TransactionRequest = anchor_tx.into(); + let req = req.chain_id(chain_id); + let req: TypedTransaction = req.into(); + let msg = req.rlp(); + let msg_hash: [u8; 32] = Keccak256::digest(&msg) + .as_slice() + .to_vec() + .try_into() + .expect("hash length isn't 32 bytes"); + // msg_hash = msg_hash % q + let msg_hash = BigUint::from_bytes_be(msg_hash.as_slice()); + let msg_hash = msg_hash.mod_floor(&*SECP256K1_Q); + let msg_hash_le = biguint_to_32bytes_le(msg_hash); + let msg_hash = ct_option_ok_or( + secp256k1::Fq::from_repr(msg_hash_le), + libsecp256k1::Error::InvalidMessage, + )?; + let k1 = secp256k1::Fq::ONE; + let sk = ct_option_ok_or( + secp256k1::Fq::from_repr((*GOLDEN_TOUCH_PRIVATEKEY).to_le_bytes()), + libsecp256k1::Error::InvalidSecretKey, + )?; + let generator = Secp256k1Affine::generator(); + let pk = generator * sk; + let pk = pk.to_affine(); + let (mut sig_r, mut sig_s) = eth_sign(k1, sk, msg_hash); + let gx1 = ct_option_ok_or( + secp256k1::Fq::from_repr(GX1.to_le_bytes()), + libsecp256k1::Error::InvalidSignature, + )?; + assert!(sig_r == gx1); + if sig_s == secp256k1::Fq::ZERO { + let k2 = secp256k1::Fq::ONE + secp256k1::Fq::ONE; + (sig_r, sig_s) = eth_sign(k2, sk, msg_hash); + let gx2 = ct_option_ok_or( + secp256k1::Fq::from_repr(GX2.to_le_bytes()), + libsecp256k1::Error::InvalidSignature, + )?; + assert!(sig_r == gx2); + } + Ok(SignData { + signature: (sig_r, sig_s), + pk, + msg_hash, + }) +} + +/// The signature of anchor transaction +pub fn sign(tx: &mut MockTransaction) { + let chain_id = (*MOCK_CHAIN_ID).as_u64(); + let _tx: Transaction = tx.to_owned().into(); + let sig_data = fixd_k_sign(&_tx, chain_id).unwrap(); + let sig_r = U256::from_little_endian(sig_data.signature.0.to_bytes().as_slice()); + let sig_s = U256::from_little_endian(sig_data.signature.1.to_bytes().as_slice()); + tx.sig_data((2712, sig_r, sig_s)); +} + +/// gen anchor call +// anchor(l1_hash,signal_root,l1_height,parent_gas_used) +pub fn anchor_call() -> Bytes { + const METHOD_SIGNATURE: u32 = 0x3d384a4b; + let mut result = Vec::new(); + result.extend_from_slice(&METHOD_SIGNATURE.to_be_bytes()); + result.extend_from_slice(&MOCK_ANCHOR_L1_HASH.to_fixed_bytes()); + result.extend_from_slice(&MOCK_ANCHOR_SIGNAL_ROOT.to_fixed_bytes()); + result.extend_from_slice(&MOCK_ANCHOR_L1_HIGHT.to_word().to_be_bytes()); + result.extend_from_slice( + &(*MOCK_ANCHOR_PARENT_GAS_USED as u64) + .to_word() + .to_be_bytes(), + ); + result.into() +} diff --git a/mock/src/block.rs b/mock/src/block.rs index 4123312933..ae0c778877 100644 --- a/mock/src/block.rs +++ b/mock/src/block.rs @@ -1,6 +1,6 @@ //! Mock Block definition and builder related methods. -use crate::{MockTransaction, MOCK_BASEFEE, MOCK_CHAIN_ID, MOCK_DIFFICULTY, MOCK_GASLIMIT}; +use crate::{MockTransaction, MOCK_BASEFEE, MOCK_CHAIN_ID, MOCK_GASLIMIT, MOCK_MIX_HASH}; use eth_types::{Address, Block, Bytes, Hash, Transaction, Word, H64, U64}; use ethers_core::types::{Bloom, OtherFields}; @@ -54,13 +54,13 @@ impl Default for MockBlock { extra_data: Bytes::default(), logs_bloom: None, timestamp: Word::from(123456789u64), - difficulty: *MOCK_DIFFICULTY, + mix_hash: *MOCK_MIX_HASH, total_difficulty: Word::zero(), + difficulty: Word::zero(), seal_fields: Vec::new(), uncles: Vec::new(), transactions: Vec::new(), size: Word::zero(), - mix_hash: Hash::zero(), nonce: H64::zero(), chain_id: *MOCK_CHAIN_ID, } diff --git a/mock/src/lib.rs b/mock/src/lib.rs index e3d286bd91..e6c7ec7246 100644 --- a/mock/src/lib.rs +++ b/mock/src/lib.rs @@ -1,11 +1,13 @@ //! Mock types and functions to generate GethData used for tests +use std::str::FromStr; -use eth_types::{address, bytecode, bytecode::Bytecode, word, Address, Bytes, Word}; +use eth_types::{address, bytecode, bytecode::Bytecode, word, Address, Bytes, Hash, Word}; use ethers_signers::LocalWallet; use lazy_static::lazy_static; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; mod account; +mod anchor; mod block; pub mod test_ctx; mod transaction; @@ -24,13 +26,17 @@ lazy_static! { /// Mock gasprice value pub static ref MOCK_GASPRICE: Word = Word::from(1u8); /// Mock BASEFEE value - pub static ref MOCK_BASEFEE: Word = Word::zero(); - /// Mock GASLIMIT value + pub static ref MOCK_BASEFEE: Word = Word::from(0u8); + /// Mock GASTIPCAP value + pub static ref MOCK_GASTIPCAP: Word = Word::from(1u8); + /// Mock GASFEECAP value + pub static ref MOCK_GASFEECAP: Word = Word::from(1u8); + /// Mock GASLIMIT value pub static ref MOCK_GASLIMIT: Word = Word::from(0x2386f26fc10000u64); /// Mock chain ID value pub static ref MOCK_CHAIN_ID: Word = Word::from(1338u64); /// Mock DIFFICULTY value - pub static ref MOCK_DIFFICULTY: Word = Word::from(0x200000u64); + pub static ref MOCK_MIX_HASH: Hash = Hash::from_str("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").unwrap(); /// Mock accounts loaded with ETH to use for test cases. pub static ref MOCK_ACCOUNTS: Vec

= vec![ address!("0x000000000000000000000000000000000cafe111"), @@ -39,6 +45,23 @@ lazy_static! { address!("0x000000000000000000000000000000000cafe444"), address!("0x000000000000000000000000000000000cafe555"), ]; + /// GOLDEN_TOUCH is Anchor's from address + pub static ref GOLDEN_TOUCH: Address = address!("0x0000777735367b36bC9B61C50022d9D0700dB4Ec"); + /// GOLDEN_TOUCH's private key + pub static ref GOLDEN_TOUCH_PRIVATEKEY: Word = word!("0x92954368afd3caa1f3ce3ead0069c1af414054aefe1ef9aeacc1bf426222ce38"); + /// Taiko l2 contract address + pub static ref MOCK_TAIKO_L2_ADDRESS: Address = address!("0x000000000000000000000000000000000cafe666"); + pub static ref MOCK_TAIKO_TREASURY_ADDRESS: Address = address!("0x000000000000000000000000000000000cafe777"); + /// Mock anchor + pub static ref MOCK_ANCHOR_GAS_LIMIT: Word = Word::from(180000); + pub static ref MOCK_ANCHOR_GAS_PRICE: Word = Word::zero(); + pub static ref MOCK_ANCHOR_L1_HASH: Hash = Hash::from_slice(&[0u8; 32]); + pub static ref MOCK_ANCHOR_SIGNAL_ROOT: Hash = Hash::from_slice(&[0u8; 32]); + pub static ref MOCK_ANCHOR_L1_HIGHT: u64 = 0; + pub static ref MOCK_ANCHOR_PARENT_GAS_USED: u32 = 0; + pub static ref MOCK_ANCHOR_TX_VALUE: Word = Word::from(0); + + /// pub /// Mock EVM codes to use for test cases. pub static ref MOCK_CODES: Vec = vec![ Bytes::from([0x60, 0x10, 0x00]), // PUSH1(0x10), STOP diff --git a/mock/src/test_ctx.rs b/mock/src/test_ctx.rs index befff9f3e0..a985aa903c 100644 --- a/mock/src/test_ctx.rs +++ b/mock/src/test_ctx.rs @@ -1,16 +1,18 @@ //! Mock types and functions to generate Test enviroments for ZKEVM tests -use crate::{eth, MockAccount, MockBlock, MockTransaction}; +use crate::{ + eth, MockAccount, MockBlock, MockTransaction, GOLDEN_TOUCH, MOCK_CODES, MOCK_TAIKO_L2_ADDRESS, + MOCK_TAIKO_TREASURY_ADDRESS, +}; use eth_types::{ geth_types::{Account, BlockConstants, GethData}, Block, Bytecode, Error, GethExecTrace, Transaction, Word, }; +pub use external_tracer::LoggerConfig; use external_tracer::{trace, TraceConfig}; use helpers::*; use itertools::Itertools; -pub use external_tracer::LoggerConfig; - /// TestContext is a type that contains all the information from a block /// required to build the circuit inputs. /// @@ -81,7 +83,7 @@ pub struct TestContext { /// chain id pub chain_id: Word, /// Account list - pub accounts: [Account; NACC], + pub accounts: Vec, /// history hashes contains most recent 256 block hashes in history, where /// the lastest one is at history_hashes[history_hashes.len() - 1]. pub history_hashes: Vec, @@ -89,6 +91,8 @@ pub struct TestContext { pub eth_block: eth_types::Block, /// Execution Trace from geth pub geth_traces: Vec, + /// In taiko context + pub is_taiko: bool, } impl From> for GethData { @@ -98,7 +102,7 @@ impl From> for GethD history_hashes: ctx.history_hashes, eth_block: ctx.eth_block, geth_traces: ctx.geth_traces.to_vec(), - accounts: ctx.accounts.into(), + accounts: ctx.accounts, } } } @@ -116,38 +120,87 @@ impl TestContext { Fb: FnOnce(&mut MockBlock, Vec) -> &mut MockBlock, FAcc: FnOnce([&mut MockAccount; NACC]), { - let mut accounts: Vec = vec![MockAccount::default(); NACC]; + Self::new_with_logger_config_and_taiko( + history_hashes, + acc_fns, + func_tx, + func_block, + logger_config, + false, + ) + } + + pub fn new_with_logger_config_and_taiko( + history_hashes: Option>, + acc_fns: FAcc, + func_tx: FTx, + func_block: Fb, + logger_config: LoggerConfig, + is_taiko: bool, + ) -> Result + where + FTx: FnOnce(Vec<&mut MockTransaction>, [MockAccount; NACC]), + Fb: FnOnce(&mut MockBlock, Vec) -> &mut MockBlock, + FAcc: FnOnce([&mut MockAccount; NACC]), + { + let more_accounts = if is_taiko { 3 } else { 0 }; + let mut accounts: Vec = vec![MockAccount::default(); NACC + more_accounts]; + if is_taiko { + accounts[0].address(*MOCK_TAIKO_TREASURY_ADDRESS); + // from golden touch to l2 contract + // add the GOLDEN_TOUCH account in the first position + accounts[1].address(*GOLDEN_TOUCH); + // add the l2 contract account in the second position + accounts[2] + .address(*MOCK_TAIKO_L2_ADDRESS) + .code(MOCK_CODES[0].clone()); + } // Build Accounts modifiers let account_refs = accounts .iter_mut() + .skip(more_accounts) .collect_vec() .try_into() .expect("Mismatched len err"); acc_fns(account_refs); - let accounts: [MockAccount; NACC] = accounts + let accounts_cloned: [MockAccount; NACC] = accounts .iter_mut() + .skip(more_accounts) .map(|acc| acc.build()) .collect_vec() .try_into() .expect("Mismatched acc len"); - let mut transactions = vec![MockTransaction::default(); NTX]; + let mut transactions = vec![MockTransaction::default(); NTX + if is_taiko { 1 } else { 0 }]; // By default, set the TxIndex and the Nonce values of the multiple transactions // of the context correlative so that any Ok test passes by default. // If the user decides to override these values, they'll then be set to whatever // inputs were provided by the user. - transactions - .iter_mut() - .enumerate() - .skip(1) - .for_each(|(idx, tx)| { - let idx = u64::try_from(idx).expect("Unexpected idx conversion error"); - tx.transaction_idx(idx).nonce(idx); - }); - let tx_refs = transactions.iter_mut().collect(); + + if is_taiko { + // add the anchor transaction in the first position + transactions[0] = MockTransaction::new_anchor(); + } + let tx_skipped = if is_taiko { 1 } else { 0 }; + let tx_refs = transactions.iter_mut().skip(tx_skipped).collect(); // Build Tx modifiers. - func_tx(tx_refs, accounts.clone()); + func_tx(tx_refs, accounts_cloned); + // Sets the transaction_idx and nonce after building the tx modifiers. Hence, if user has + // overridden these values above using the tx modifiers, that will be ignored. + let mut acc_tx_count = vec![0u64; NACC + more_accounts]; + transactions.iter_mut().enumerate().for_each(|(idx, tx)| { + let idx = u64::try_from(idx).expect("Unexpected idx conversion error"); + tx.transaction_idx(idx); + if let Some((pos, from_acc)) = accounts + .iter() + .find_position(|acc| acc.address == tx.from.address()) + { + tx.nonce(from_acc.nonce + acc_tx_count[pos]); + acc_tx_count[pos] += 1; + } + }); + let transactions: Vec = transactions.iter_mut().map(|tx| tx.build()).collect(); @@ -158,20 +211,15 @@ impl TestContext { let chain_id = block.chain_id; let block = Block::::from(block); - let accounts: [Account; NACC] = accounts - .iter() - .cloned() - .map(Account::from) - .collect_vec() - .try_into() - .expect("Mismatched acc len"); + let accounts = accounts.iter().cloned().map(Account::from).collect_vec(); let geth_traces = gen_geth_traces( chain_id, block.clone(), - accounts.to_vec(), + accounts.clone(), history_hashes.clone(), logger_config, + is_taiko, )?; Ok(Self { @@ -180,6 +228,7 @@ impl TestContext { history_hashes: history_hashes.unwrap_or_default(), eth_block: block, geth_traces, + is_taiko, }) } @@ -209,6 +258,28 @@ impl TestContext { ) } + /// Create a new TestContext used for taiko environment. + pub fn new_with_taiko( + history_hashes: Option>, + acc_fns: FAcc, + func_tx: FTx, + func_block: Fb, + ) -> Result + where + FTx: FnOnce(Vec<&mut MockTransaction>, [MockAccount; NACC]), + Fb: FnOnce(&mut MockBlock, Vec) -> &mut MockBlock, + FAcc: FnOnce([&mut MockAccount; NACC]), + { + Self::new_with_logger_config_and_taiko( + history_hashes, + acc_fns, + func_tx, + func_block, + LoggerConfig::default(), + true, + ) + } + /// 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:: @@ -232,6 +303,7 @@ pub fn gen_geth_traces( accounts: Vec, history_hashes: Option>, logger_config: LoggerConfig, + is_taiko: bool, ) -> Result, Error> { let trace_config = TraceConfig { chain_id, @@ -247,6 +319,7 @@ pub fn gen_geth_traces( .map(eth_types::geth_types::Transaction::from) .collect(), logger_config, + taiko: is_taiko, }; let traces = trace(&trace_config)?; Ok(traces) diff --git a/mock/src/transaction.rs b/mock/src/transaction.rs index 1b6c6ccd1f..9a6393df85 100644 --- a/mock/src/transaction.rs +++ b/mock/src/transaction.rs @@ -1,13 +1,19 @@ //! Mock Transaction definition and builder related methods. -use super::{MOCK_ACCOUNTS, MOCK_CHAIN_ID, MOCK_GASPRICE}; +use crate::MOCK_BASEFEE; + +use super::{ + GOLDEN_TOUCH, MOCK_ACCOUNTS, MOCK_ANCHOR_GAS_LIMIT, MOCK_ANCHOR_GAS_PRICE, + MOCK_ANCHOR_TX_VALUE, MOCK_CHAIN_ID, MOCK_GASFEECAP, MOCK_GASPRICE, MOCK_GASTIPCAP, + MOCK_TAIKO_L2_ADDRESS, +}; use eth_types::{ geth_types::Transaction as GethTransaction, word, AccessList, Address, Bytes, Hash, Transaction, Word, U64, }; use ethers_core::{ rand::{CryptoRng, RngCore}, - types::{OtherFields, TransactionRequest}, + types::{Eip1559TransactionRequest, OtherFields}, }; use ethers_signers::{LocalWallet, Signer}; use lazy_static::lazy_static; @@ -126,6 +132,7 @@ pub struct MockTransaction { pub from: AddrOrWallet, pub to: Option, pub value: Word, + // gas_price == min(max_fee_per_gas, max_priority_fee_per_gas + base_fee_per_gas) pub gas_price: Word, pub gas: Word, pub input: Bytes, @@ -156,10 +163,10 @@ impl Default for MockTransaction { v: None, r: None, s: None, - transaction_type: U64::zero(), + transaction_type: U64::from(2), access_list: AccessList::default(), - max_priority_fee_per_gas: Word::zero(), - max_fee_per_gas: Word::zero(), + max_priority_fee_per_gas: *MOCK_GASTIPCAP, + max_fee_per_gas: *MOCK_GASFEECAP, chain_id: *MOCK_CHAIN_ID, } } @@ -198,6 +205,26 @@ impl From for GethTransaction { } } +impl MockTransaction { + /// create a mock anchor transaction + pub fn new_anchor() -> Self { + let mut tx = MockTransaction::default(); + tx.from(*GOLDEN_TOUCH); + tx.to(*MOCK_TAIKO_L2_ADDRESS); + tx.gas(*MOCK_ANCHOR_GAS_LIMIT) + .gas_price(*MOCK_ANCHOR_GAS_PRICE) + .max_priority_fee_per_gas(Word::zero()) + .max_fee_per_gas(*MOCK_BASEFEE) + .from(*GOLDEN_TOUCH) + .to(*MOCK_TAIKO_L2_ADDRESS) + .input(crate::anchor::anchor_call()) + .nonce(0) + .value(*MOCK_ANCHOR_TX_VALUE); + crate::anchor::sign(&mut tx); + tx + } +} + impl MockTransaction { /// Tx Hash computed based on the fields of the Tx by /// default unless `Some(hash)` is specified on build process. @@ -307,14 +334,15 @@ impl MockTransaction { /// Consumes the mutable ref to the MockTransaction returning the structure /// by value. pub fn build(&mut self) -> Self { - let tx = TransactionRequest::new() + let tx = Eip1559TransactionRequest::new() .from(self.from.address()) .to(self.to.clone().unwrap_or_default().address()) .nonce(self.nonce) .value(self.value) .data(self.input.clone()) .gas(self.gas) - .gas_price(self.gas_price) + .max_priority_fee_per_gas(self.max_priority_fee_per_gas) + .max_fee_per_gas(self.max_fee_per_gas) .chain_id(self.chain_id.low_u64()); match (self.v, self.r, self.s) { diff --git a/testool/src/statetest/executor.rs b/testool/src/statetest/executor.rs index c2c365d8f1..d738de1fb5 100644 --- a/testool/src/statetest/executor.rs +++ b/testool/src/statetest/executor.rs @@ -131,7 +131,7 @@ fn into_traceconfig(st: StateTest) -> (String, TraceConfig, StateTestResult) { coinbase: st.env.current_coinbase, timestamp: U256::from(st.env.current_timestamp), number: U64::from(st.env.current_number), - difficulty: st.env.current_difficulty, + mix_hash: st.env.current_mix_hash, gas_limit: U256::from(st.env.current_gas_limit), base_fee: U256::one(), }, @@ -222,7 +222,7 @@ pub fn run_test( author: Some(trace_config.block_constants.coinbase), timestamp: trace_config.block_constants.timestamp, number: Some(U64::from(trace_config.block_constants.number.as_u64())), - difficulty: trace_config.block_constants.difficulty, + mix_hash: Some(trace_config.block_constants.mix_hash), gas_limit: trace_config.block_constants.gas_limit, base_fee_per_gas: Some(trace_config.block_constants.base_fee), transactions, diff --git a/testool/src/statetest/json.rs b/testool/src/statetest/json.rs index 0b89dc6c56..467222edd9 100644 --- a/testool/src/statetest/json.rs +++ b/testool/src/statetest/json.rs @@ -13,7 +13,7 @@ use std::collections::HashMap; #[serde(rename_all = "camelCase")] struct TestEnv { current_coinbase: String, - current_difficulty: String, + current_mix_hash: String, current_gas_limit: String, current_number: String, current_timestamp: String, @@ -192,7 +192,7 @@ impl<'a> JsonStateTestBuilder<'a> { fn parse_env(env: &TestEnv) -> Result { Ok(Env { current_coinbase: parse::parse_address(&env.current_coinbase)?, - current_difficulty: parse::parse_u256(&env.current_difficulty)?, + current_mix_hash: parse::parse_hash(&env.current_mix_hash)?, current_gas_limit: parse::parse_u64(&env.current_gas_limit)?, current_number: parse::parse_u64(&env.current_number)?, current_timestamp: parse::parse_u64(&env.current_timestamp)?, @@ -305,7 +305,7 @@ mod test { }, "env" : { "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", - "currentDifficulty" : "0x20000", + "currentMixHash" : "0x20000", "currentGasLimit" : "0xFF112233445566", "currentNumber" : "1", "currentTimestamp" : "1000", @@ -371,7 +371,9 @@ mod test { id: "add11_d0_g0_v0".to_string(), env: Env { current_coinbase: Address::from_str("0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba")?, - current_difficulty: U256::from(131072u64), + current_mix_hash: H256::from_str( + "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + )?, current_gas_limit: 0xFF112233445566, current_number: 1, current_timestamp: 1000, diff --git a/testool/src/statetest/spec.rs b/testool/src/statetest/spec.rs index 10f61f4cbd..5045e24ced 100644 --- a/testool/src/statetest/spec.rs +++ b/testool/src/statetest/spec.rs @@ -6,7 +6,7 @@ use std::{collections::HashMap, str::FromStr}; #[derive(PartialEq, Eq, Debug, Clone)] pub struct Env { pub current_coinbase: Address, - pub current_difficulty: U256, + pub current_mix_hash: H256, pub current_gas_limit: u64, pub current_number: u64, pub current_timestamp: u64, @@ -90,10 +90,7 @@ impl std::fmt::Display for StateTest { } table.add_row(row!["coinbase", format!("{:?}", self.env.current_coinbase)]); - table.add_row(row![ - "difficulty", - format!("{}", self.env.current_difficulty) - ]); + table.add_row(row!["mix_hash", format!("{}", self.env.current_mix_hash)]); table.add_row(row!["number", format!("{}", self.env.current_number)]); table.add_row(row!["timestamp", format!("{}", self.env.current_timestamp)]); table.add_row(row!["prev_hash", format!("{:?}", self.env.previous_hash)]); @@ -262,7 +259,7 @@ impl StateTest { id: String::default(), env: Env { current_coinbase: *mock::MOCK_COINBASE, - current_difficulty: U256::default(), + current_mix_hash: H256::default(), current_gas_limit: 16000000, current_number: 1, current_timestamp: 1, diff --git a/testool/src/statetest/yaml.rs b/testool/src/statetest/yaml.rs index fadd4fc682..22fb507c95 100644 --- a/testool/src/statetest/yaml.rs +++ b/testool/src/statetest/yaml.rs @@ -204,7 +204,7 @@ impl<'a> YamlStateTestBuilder<'a> { fn parse_env(yaml: &Yaml) -> Result { Ok(Env { current_coinbase: Self::parse_address(&yaml["currentCoinbase"])?, - current_difficulty: Self::parse_u256(&yaml["currentDifficulty"])?, + current_mix_hash: Self::parse_hash(&yaml["currentMixHash"])?, current_gas_limit: Self::parse_u64(&yaml["currentGasLimit"])?, current_number: Self::parse_u64(&yaml["currentNumber"])?, current_timestamp: Self::parse_u64(&yaml["currentTimestamp"])?, @@ -436,7 +436,7 @@ mod test { arith: env: currentCoinbase: 2adc25665018aa1fe0e6bc666dac8fc2697ff9ba - currentDifficulty: 0x20000 + currentMixHash: 0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347 currentGasLimit: {{ gas_limit }} currentNumber: 1 currentTimestamp: 1000 @@ -600,7 +600,9 @@ arith: id: "arith_d0_g0_v0".into(), env: Env { current_coinbase: address!("0x2adc25665018aa1fe0e6bc666dac8fc2697ff9ba"), - current_difficulty: U256::from(0x20000u64), + current_mix_hash: H256::from_str( + "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + )?, current_number: 1, current_timestamp: 1000, current_gas_limit: 100000000, diff --git a/zkevm-circuits/src/anchor_tx_circuit.rs b/zkevm-circuits/src/anchor_tx_circuit.rs index c2c7f3e187..327806ccbc 100644 --- a/zkevm-circuits/src/anchor_tx_circuit.rs +++ b/zkevm-circuits/src/anchor_tx_circuit.rs @@ -7,16 +7,15 @@ pub use dev::TestAnchorTxCircuit; pub(crate) mod sign_verify; #[cfg(any(feature = "test", test))] mod test; -#[cfg(any(feature = "test", test))] -pub(crate) use test::{add_anchor_accounts, add_anchor_tx, sign_tx}; use crate::{ evm_circuit::util::constraint_builder::{BaseConstraintBuilder, ConstrainBuilderCommon}, table::{byte_table::ByteTable, LookupTable, PiFieldTag, PiTable, TxFieldTag, TxTable}, tx_circuit::TX_LEN, util::{Challenges, SubCircuit, SubCircuitConfig}, - witness::{self, ProtocolInstance, Transaction}, + witness::{self, Transaction}, }; +use bus_mapping::circuit_input_builder::ProtocolInstance; use eth_types::{Field, ToScalar}; use gadgets::util::{select, Expr}; use halo2_proofs::{ @@ -33,7 +32,8 @@ use self::sign_verify::GOLDEN_TOUCH_ADDRESS; const ANCHOR_TX_ID: usize = 1; const ANCHOR_TX_VALUE: u64 = 0; const ANCHOR_TX_IS_CREATE: bool = false; -const ANCHOR_TX_GAS_PRICE: u64 = 1; +const ANCHOR_TX_GAS_PRICE: u64 = 0; +const ANCHOR_TX_GAS_TIP_CAP: u64 = 0; const MAX_DEGREE: usize = 9; const BYTE_POW_BASE: u64 = 1 << 8; @@ -222,6 +222,10 @@ impl AnchorTxCircuitConfig { TxFieldTag::GasPrice, Value::known(F::from(ANCHOR_TX_GAS_PRICE)), ), + ( + TxFieldTag::GasTipCap, + Value::known(F::from(ANCHOR_TX_GAS_TIP_CAP)), + ), ( TxFieldTag::CallerAddress, Value::known( @@ -429,7 +433,7 @@ impl SubCircuit for AnchorTxCircuit { block.circuits_params.max_calldata, block.txs.first().unwrap().clone(), block.txs.clone(), - block.protocol_instance.clone(), + block.protocol_instance.clone().unwrap(), ) } diff --git a/zkevm-circuits/src/anchor_tx_circuit/dev.rs b/zkevm-circuits/src/anchor_tx_circuit/dev.rs index 3bcb061faa..25015258b2 100644 --- a/zkevm-circuits/src/anchor_tx_circuit/dev.rs +++ b/zkevm-circuits/src/anchor_tx_circuit/dev.rs @@ -3,8 +3,9 @@ use crate::{ anchor_tx_circuit::{AnchorTxCircuitConfig, AnchorTxCircuitConfigArgs}, table::{byte_table::ByteTable, PiTable, TxTable}, util::{Challenges, SubCircuit, SubCircuitConfig}, - witness::{self, ProtocolInstance}, + witness, }; +use bus_mapping::circuit_input_builder::ProtocolInstance; use eth_types::{Field, H256}; use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner}, @@ -22,7 +23,7 @@ impl TestAnchorTxCircuit { /// Create a new test circuit from a block. pub fn new_from_block(block: &witness::Block) -> Self { TestAnchorTxCircuit { - protocol_instance: block.protocol_instance.clone(), + protocol_instance: block.protocol_instance.clone().unwrap(), circuit: AnchorTxCircuit::new_from_block(block), } } diff --git a/zkevm-circuits/src/anchor_tx_circuit/test.rs b/zkevm-circuits/src/anchor_tx_circuit/test.rs index b60ebe8ef3..7c628b7fd5 100644 --- a/zkevm-circuits/src/anchor_tx_circuit/test.rs +++ b/zkevm-circuits/src/anchor_tx_circuit/test.rs @@ -15,7 +15,7 @@ use bus_mapping::{ }; use eth_types::{ address, bytecode, - geth_types::{GethData, Transaction}, + geth_types::GethData, sign_types::{biguint_to_32bytes_le, ct_option_ok_or, sign, SignData, SECP256K1_Q}, word, Address, Field, ToBigEndian, ToLittleEndian, ToWord, Word, H256, U256, }; @@ -47,56 +47,6 @@ use num_bigint::BigUint; use once_cell::sync::Lazy; use sha3::{Digest, Keccak256}; -pub(crate) fn anchor_sign( - anchor_tx: &Transaction, - chain_id: u64, -) -> Result { - // msg = rlp([nonce, gasPrice, gas, to, value, data, sig_v, r, s]) - let req: TransactionRequest = anchor_tx.into(); - let msg = req.chain_id(chain_id).rlp(); - let msg_hash: [u8; 32] = Keccak256::digest(&msg) - .as_slice() - .to_vec() - .try_into() - .expect("hash length isn't 32 bytes"); - // msg_hash = msg_hash % q - let msg_hash = BigUint::from_bytes_be(msg_hash.as_slice()); - let msg_hash = msg_hash.mod_floor(&*SECP256K1_Q); - let msg_hash_le = biguint_to_32bytes_le(msg_hash); - let msg_hash = ct_option_ok_or( - secp256k1::Fq::from_repr(msg_hash_le), - libsecp256k1::Error::InvalidMessage, - )?; - let k1 = secp256k1::Fq::ONE; - let sk = ct_option_ok_or( - secp256k1::Fq::from_repr(GOLDEN_TOUCH_PRIVATEKEY.to_le_bytes()), - libsecp256k1::Error::InvalidSecretKey, - )?; - let generator = Secp256k1Affine::generator(); - let pk = generator * sk; - let pk = pk.to_affine(); - let (mut sig_r, mut sig_s) = sign(k1, sk, msg_hash); - let gx1 = ct_option_ok_or( - secp256k1::Fq::from_repr(GX1.to_le_bytes()), - libsecp256k1::Error::InvalidSignature, - )?; - assert!(sig_r == gx1); - if sig_s == secp256k1::Fq::ZERO { - let k2 = secp256k1::Fq::ONE + secp256k1::Fq::ONE; - (sig_r, sig_s) = sign(k2, sk, msg_hash); - let gx2 = ct_option_ok_or( - secp256k1::Fq::from_repr(GX2.to_le_bytes()), - libsecp256k1::Error::InvalidSignature, - )?; - assert!(sig_r == gx2); - } - Ok(SignData { - signature: (sig_r, sig_s), - pk, - msg_hash, - }) -} - fn run(block: &Block, sign_hash: Option) -> Result<(), Vec> { let k = log2_ceil( AnchorTxCircuit::::unusable_rows() @@ -113,53 +63,10 @@ fn run(block: &Block, sign_hash: Option) -> Result<(), Vec( - accs: [&mut MockAccount; NACC], - acc_fns: FAcc, - protocol_instance: &ProtocolInstance, -) where - FAcc: FnOnce([&mut MockAccount; NACC]), -{ - let code = bytecode! { - PUSH1(0x01) // value - PUSH1(0x02) // key - SSTORE - - PUSH3(0xbb) - }; - accs[0] - .address(*GOLDEN_TOUCH_ADDRESS) - .balance(Word::from(1u64 << 20)); - accs[1].address(protocol_instance.l2_contract).code(code); - acc_fns(accs); -} - -pub(crate) fn add_anchor_tx( - mut txs: Vec<&mut MockTransaction>, - accs: [MockAccount; NACC], - func_tx: FTx, - extra_func_tx: fn(&mut MockTransaction), - protocol_instance: &ProtocolInstance, -) where - FTx: FnOnce(Vec<&mut MockTransaction>, [MockAccount; NACC]), -{ - txs[0] - .gas(protocol_instance.anchor_gas_limit.to_word()) - .gas_price(ANCHOR_TX_GAS_PRICE.to_word()) - .from(*GOLDEN_TOUCH_ADDRESS) - .to(protocol_instance.l2_contract) - .input(protocol_instance.anchor_call()) - .nonce(0) - .value(ANCHOR_TX_VALUE.to_word()); - extra_func_tx(txs[0]); - func_tx(txs, accs); -} - fn gen_block( max_txs: usize, max_calldata: usize, protocol_instance: ProtocolInstance, - extra_func_tx: fn(&mut MockTransaction), ) -> Block { let chain_id = (*MOCK_CHAIN_ID).as_u64(); let mut wallets = HashMap::new(); @@ -171,14 +78,10 @@ fn gen_block( wallets.insert(*GOLDEN_TOUCH_ADDRESS, wallet); - let block: GethData = TestContext::<2, NUM_TXS>::new( + let block: GethData = TestContext::<0, NUM_TXS>::new_with_taiko( None, - |accs| { - add_anchor_accounts(accs, |_| {}, &protocol_instance); - }, - |txs, accs| { - add_anchor_tx(txs, accs, |_, _| {}, extra_func_tx, &protocol_instance); - }, + |_accs| {}, + |_txs, _accs| {}, |block, _tx| block, ) .unwrap() @@ -194,20 +97,11 @@ fn gen_block( .handle_block(&block.eth_block, &block.geth_traces) .unwrap(); let mut block = block_convert::(&builder.block, &builder.code_db).unwrap(); - block.protocol_instance = protocol_instance; + block.protocol_instance = Some(protocol_instance); block } -pub(crate) fn sign_tx(tx: &mut MockTransaction) { - let chain_id = (*MOCK_CHAIN_ID).as_u64(); - let _tx: Transaction = tx.to_owned().into(); - let sig_data = anchor_sign(&_tx, chain_id).unwrap(); - let sig_r = U256::from_little_endian(sig_data.signature.0.to_bytes().as_slice()); - let sig_s = U256::from_little_endian(sig_data.signature.1.to_bytes().as_slice()); - tx.sig_data((2712, sig_r, sig_s)); -} - -fn sign_tx_r_is_gx2(tx: &mut MockTransaction) { +fn sign_tx_r_is_gx2(tx: &mut Transaction) { let msg_hash = *N - *GX1_MUL_PRIVATEKEY; let msg_hash = ct_option_ok_or( secp256k1::Fq::from_repr(msg_hash.to_le_bytes()), @@ -223,7 +117,9 @@ fn sign_tx_r_is_gx2(tx: &mut MockTransaction) { let (sig_r, sig_s) = sign(k2, sk, msg_hash); let sig_r = U256::from_little_endian(sig_r.to_bytes().as_slice()); let sig_s = U256::from_little_endian(sig_s.to_bytes().as_slice()); - tx.sig_data((2712, sig_r, sig_s)); + tx.v = 2712; + tx.r = sig_r; + tx.s = sig_s; } #[test] @@ -236,22 +132,17 @@ fn anchor_tx_circuit_unusable_rows() { #[test] fn anchor_test() { - let protocol_instance = ProtocolInstance { - anchor_gas_limit: 150000, - ..Default::default() - }; - let block = gen_block::<1>(2, 200, protocol_instance, sign_tx); + let protocol_instance = Default::default(); + let block = gen_block::<0>(2, 200, protocol_instance); assert_eq!(run::(&block, None), Ok(())); } #[test] fn anchor_test_when_sign_r_is_gx2() { - let protocol_instance = ProtocolInstance { - anchor_gas_limit: 150000, - ..Default::default() - }; + let protocol_instance = Default::default(); let msg_hash = *N - *GX1_MUL_PRIVATEKEY; let msg_hash = H256::from(msg_hash.to_le_bytes()); - let block = gen_block::<1>(2, 200, protocol_instance, sign_tx_r_is_gx2); + let mut block = gen_block::<0>(2, 200, protocol_instance); + sign_tx_r_is_gx2(&mut block.txs[0]); assert_eq!(run::(&block, Some(msg_hash)), Ok(())); } diff --git a/zkevm-circuits/src/bin/stats/helpers.rs b/zkevm-circuits/src/bin/stats/helpers.rs index 01117a48c0..502084458c 100644 --- a/zkevm-circuits/src/bin/stats/helpers.rs +++ b/zkevm-circuits/src/bin/stats/helpers.rs @@ -117,7 +117,7 @@ pub(crate) fn print_circuit_stats_by_states( ) { let mut implemented_states = Vec::new(); for state in ExecutionState::iter() { - let height = state.get_step_height_option(); + let height = state.get_step_height_option(false); if height.is_some() { implemented_states.push(state); } diff --git a/zkevm-circuits/src/bin/stats/main.rs b/zkevm-circuits/src/bin/stats/main.rs index 30c8fc9a27..da7749b040 100644 --- a/zkevm-circuits/src/bin/stats/main.rs +++ b/zkevm-circuits/src/bin/stats/main.rs @@ -60,7 +60,7 @@ fn evm_states_stats() { PUSH2(0x50) }, }, - |_, state, _| state.get_step_height_option().unwrap(), + |_, state, _| state.get_step_height_option(false).unwrap(), ); } diff --git a/zkevm-circuits/src/evm_circuit.rs b/zkevm-circuits/src/evm_circuit.rs index 86d1aad98a..46056ae18e 100644 --- a/zkevm-circuits/src/evm_circuit.rs +++ b/zkevm-circuits/src/evm_circuit.rs @@ -5,6 +5,7 @@ use halo2_proofs::{ circuit::{Layouter, SimpleFloorPlanner, Value}, plonk::*, }; +use snark_verifier_sdk::CircuitExt; mod execution; pub mod param; @@ -68,6 +69,8 @@ pub struct EvmCircuitConfigArgs { pub keccak_table: KeccakTable, /// ExpTable pub exp_table: ExpTable, + /// Taiko + pub is_taiko: bool, } impl SubCircuitConfig for EvmCircuitConfig { @@ -85,6 +88,7 @@ impl SubCircuitConfig for EvmCircuitConfig { copy_table, keccak_table, exp_table, + is_taiko, }: Self::ConfigArgs, ) -> Self { let fixed_table = [(); 4].map(|_| meta.fixed_column()); @@ -101,6 +105,7 @@ impl SubCircuitConfig for EvmCircuitConfig { ©_table, &keccak_table, &exp_table, + is_taiko, )); meta.annotate_lookup_any_column(byte_table[0], || "byte_range"); @@ -222,7 +227,7 @@ impl EvmCircuit { let mut num_rows = 0; for transaction in &block.txs { for step in &transaction.steps { - num_rows += step.execution_state().get_step_height(); + num_rows += step.execution_state().get_step_height(block.is_taiko()); } } @@ -317,6 +322,15 @@ pub(crate) mod cached { let config = EvmCircuit::::configure(&mut meta); Cache { cs: meta, config } }; + + static ref CACHE_WITH_TAIKO: Cache = { + let mut meta = ConstraintSystem::::default(); + let config = EvmCircuit::::configure_with_params( + &mut meta, + EvmCircuitParams { is_taiko: true }, + ); + Cache { cs: meta, config } + }; } /// Wrapper over the EvmCircuit that behaves the same way and also @@ -329,15 +343,31 @@ pub(crate) mod cached { impl Circuit for EvmCircuitCached { type Config = (EvmCircuitConfig, Challenges); type FloorPlanner = SimpleFloorPlanner; - type Params = (); + type Params = EvmCircuitParams; fn without_witnesses(&self) -> Self { Self(self.0.without_witnesses()) } fn configure(meta: &mut ConstraintSystem) -> Self::Config { - *meta = CACHE.cs.clone(); - CACHE.config.clone() + Self::configure_with_params(meta, Default::default()) + } + + fn params(&self) -> Self::Params { + self.0.params() + } + + fn configure_with_params( + meta: &mut ConstraintSystem, + EvmCircuitParams { is_taiko }: Self::Params, + ) -> Self::Config { + if is_taiko { + *meta = CACHE_WITH_TAIKO.cs.clone(); + CACHE_WITH_TAIKO.config.clone() + } else { + *meta = CACHE.cs.clone(); + CACHE.config.clone() + } } fn synthesize( @@ -356,17 +386,46 @@ pub(crate) mod cached { } } +/// Evm Circuit configuration parameters +#[derive(Default)] +pub struct EvmCircuitParams { + is_taiko: bool, +} + +impl CircuitExt for EvmCircuit { + fn num_instance(&self) -> Vec { + self.instance().iter().map(|v| v.len()).collect_vec() + } + + fn instances(&self) -> Vec> { + self.instance() + } +} + // Always exported because of `EXECUTION_STATE_HEIGHT_MAP` impl Circuit for EvmCircuit { type Config = (EvmCircuitConfig, Challenges); type FloorPlanner = SimpleFloorPlanner; - type Params = (); + type Params = EvmCircuitParams; fn without_witnesses(&self) -> Self { Self::default() } fn configure(meta: &mut ConstraintSystem) -> Self::Config { + Self::configure_with_params(meta, Self::Params::default()) + } + + fn params(&self) -> Self::Params { + EvmCircuitParams { + is_taiko: self.block.as_ref().unwrap().is_taiko(), + } + } + + fn configure_with_params( + meta: &mut ConstraintSystem, + EvmCircuitParams { is_taiko }: Self::Params, + ) -> Self::Config { let tx_table = TxTable::construct(meta); let rw_table = RwTable::construct(meta); let bytecode_table = BytecodeTable::construct(meta); @@ -390,6 +449,7 @@ impl Circuit for EvmCircuit { copy_table, keccak_table, exp_table, + is_taiko, }, ), challenges, @@ -458,7 +518,7 @@ mod evm_circuit_stats { fn evm_circuit_unusable_rows() { assert_eq!( EvmCircuit::::unusable_rows(), - unusable_rows::>(()), + unusable_rows::>(Default::default()), ) } diff --git a/zkevm-circuits/src/evm_circuit/execution.rs b/zkevm-circuits/src/evm_circuit/execution.rs index b533675108..553226a87e 100644 --- a/zkevm-circuits/src/evm_circuit/execution.rs +++ b/zkevm-circuits/src/evm_circuit/execution.rs @@ -96,6 +96,7 @@ mod pc; mod pop; mod precompiles; mod push; +mod push0; mod return_revert; mod returndatacopy; mod returndatasize; @@ -166,6 +167,7 @@ use origin::OriginGadget; use pc::PcGadget; use pop::PopGadget; use push::PushGadget; +use push0::DummyPush0Gadget; use return_revert::ReturnRevertGadget; use returndatacopy::ReturnDataCopyGadget; use returndatasize::ReturnDataSizeGadget; @@ -262,6 +264,7 @@ pub struct ExecutionConfig { pc_gadget: Box>, pop_gadget: Box>, push_gadget: Box>, + push0_gadget: Box>, return_revert_gadget: Box>, sar_gadget: Box>, sdiv_smod_gadget: Box>, @@ -329,6 +332,7 @@ impl ExecutionConfig { copy_table: &dyn LookupTable, keccak_table: &dyn LookupTable, exp_table: &dyn LookupTable, + is_taiko: bool, ) -> Self { let mut instrument = Instrument::default(); let q_usable = meta.complex_selector(); @@ -471,6 +475,7 @@ impl ExecutionConfig { &mut height_map, &mut stored_expressions_map, &mut instrument, + is_taiko, )) })() }; @@ -525,6 +530,7 @@ impl ExecutionConfig { pc_gadget: configure_gadget!(), pop_gadget: configure_gadget!(), push_gadget: configure_gadget!(), + push0_gadget: configure_gadget!(), return_revert_gadget: configure_gadget!(), sdiv_smod_gadget: configure_gadget!(), selfbalance_gadget: configure_gadget!(), @@ -615,6 +621,7 @@ impl ExecutionConfig { height_map: &mut HashMap, stored_expressions_map: &mut HashMap>>, instrument: &mut Instrument, + is_taiko: bool, ) -> G { // Configure the gadget with the max height first so we can find out the actual // height @@ -625,6 +632,7 @@ impl ExecutionConfig { dummy_step_next, challenges, G::EXECUTION_STATE, + is_taiko, ); G::configure(&mut cb); let (_, _, height) = cb.build(); @@ -638,6 +646,7 @@ impl ExecutionConfig { step_next.clone(), challenges, G::EXECUTION_STATE, + is_taiko, ); let gadget = G::configure(&mut cb); @@ -929,7 +938,7 @@ impl ExecutionConfig { if next.is_none() { break; } - let height = step.execution_state().get_step_height(); + let height = step.execution_state().get_step_height(block.is_taiko()); // Assign the step witness self.assign_exec_step( @@ -960,7 +969,7 @@ impl ExecutionConfig { ); // return Err(Error::Synthesis); } - let height = ExecutionState::EndBlock.get_step_height(); + let height = ExecutionState::EndBlock.get_step_height(block.is_taiko()); debug_assert_eq!(height, 1); let last_row = evm_rows - 1; log::trace!( @@ -987,7 +996,7 @@ impl ExecutionConfig { } // part3: assign the last EndBlock at offset `evm_rows - 1` - let height = ExecutionState::EndBlock.get_step_height(); + let height = ExecutionState::EndBlock.get_step_height(block.is_taiko()); debug_assert_eq!(height, 1); log::trace!("assign last EndBlock at offset {}", offset); self.assign_exec_step( diff --git a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs index 39c404ce50..dc1a2f7fca 100644 --- a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs @@ -1,7 +1,7 @@ use crate::{ evm_circuit::{ execution::ExecutionGadget, - param::{N_BYTES_ACCOUNT_ADDRESS, N_BYTES_GAS, N_BYTES_WORD}, + param::{N_BYTES_ACCOUNT_ADDRESS, N_BYTES_GAS, N_BYTES_U64, N_BYTES_WORD}, step::ExecutionState, util::{ and, @@ -12,14 +12,16 @@ use crate::{ }, is_precompiled, math_gadget::{ - ContractCreateGadget, IsEqualGadget, IsZeroGadget, MulWordByU64Gadget, - RangeCheckGadget, + ConstantDivisionGadget, ContractCreateGadget, IsEqualGadget, IsZeroGadget, + MulWordByU64Gadget, RangeCheckGadget, }, not, or, select, CachedRegion, Cell, StepRws, Word, }, witness::{Block, Call, ExecStep, Transaction}, }, - table::{AccountFieldTag, CallContextFieldTag, TxFieldTag as TxContextFieldTag}, + table::{ + AccountFieldTag, BlockContextFieldTag, CallContextFieldTag, TxFieldTag as TxContextFieldTag, + }, util::Expr, }; use eth_types::{evm_types::GasCost, Field, ToLittleEndian, ToScalar}; @@ -42,6 +44,7 @@ pub(crate) struct BeginTxGadget { tx_value: Word, tx_call_data_length: Cell, tx_call_data_gas_cost: Cell, + tx_call_data_word_length: ConstantDivisionGadget, reversion_info: ReversionInfo, sufficient_gas_left: RangeCheckGadget, transfer_with_gas_fee: TransferWithGasFeeGadget, @@ -51,6 +54,12 @@ pub(crate) struct BeginTxGadget { create: ContractCreateGadget, callee_not_exists: IsZeroGadget, is_caller_callee_equal: Cell, + // EIP-3651 (Warm COINBASE) + coinbase: Cell, + // Caller, callee and a list addresses are added to the access list before + // coinbase, and may be duplicate. + // + is_coinbase_warm: Cell, } impl ExecutionGadget for BeginTxGadget { @@ -121,19 +130,30 @@ impl ExecutionGadget for BeginTxGadget { None, ); // rwc_delta += 1 - // TODO: Implement EIP 1559 (currently it only supports legacy // transaction format) // Calculate transaction gas fee let mul_gas_fee_by_gas = MulWordByU64Gadget::construct(cb, tx_gas_price.clone(), tx_gas.expr()); + let tx_call_data_word_length = + ConstantDivisionGadget::construct(cb, tx_call_data_length.expr() + 31.expr(), 32); + + // Calculate gas cost of init code for EIP-3860. + let init_code_gas_cost = select::expr( + tx_is_create.expr(), + tx_call_data_word_length.quotient().expr() + * eth_types::evm_types::INIT_CODE_WORD_GAS.expr(), + 0.expr(), + ); + // TODO: Take gas cost of access list (EIP 2930) into consideration. // Use intrinsic gas let intrinsic_gas_cost = select::expr( tx_is_create.expr(), GasCost::CREATION_TX.expr(), GasCost::TX.expr(), - ) + tx_call_data_gas_cost.expr(); + ) + tx_call_data_gas_cost.expr() + + init_code_gas_cost; // Check gas_left is sufficient let gas_left = tx_gas.expr() - intrinsic_gas_cost; @@ -158,6 +178,18 @@ impl ExecutionGadget for BeginTxGadget { None, ); // rwc_delta += 1 + // Query coinbase address. + let coinbase = cb.query_cell(); + let is_coinbase_warm = cb.query_bool(); + cb.block_lookup(BlockContextFieldTag::Coinbase.expr(), None, coinbase.expr()); + cb.account_access_list_write( + tx_id.expr(), + coinbase.expr(), + 1.expr(), + is_coinbase_warm.expr(), + None, + ); // rwc_delta += 1 + // Read code_hash of callee let phase2_code_hash = cb.query_cell_phase2(); let is_empty_code_hash = @@ -262,8 +294,9 @@ impl ExecutionGadget for BeginTxGadget { // - Write CallContext IsPersistent // - Write CallContext IsSuccess // - Write Account (Caller) Nonce - // - Write TxAccessListAccount - // - Write TxAccessListAccount + // - Write TxAccessListAccount (Caller) + // - Write TxAccessListAccount (Callee) + // - Write TxAccessListAccount (Coinbase) for EIP-3651 // - a TransferWithGasFeeGadget // - Write Account (Callee) Nonce (Reversible) // - Write CallContext Depth @@ -279,7 +312,7 @@ impl ExecutionGadget for BeginTxGadget { // - Write CallContext IsRoot // - Write CallContext IsCreate // - Write CallContext CodeHash - rw_counter: Delta(21.expr() + transfer_with_gas_fee.rw_delta()), + rw_counter: Delta(22.expr() + transfer_with_gas_fee.rw_delta()), call_id: To(call_id.expr()), is_root: To(true.expr()), is_create: To(tx_is_create.expr()), @@ -318,11 +351,12 @@ impl ExecutionGadget for BeginTxGadget { // - Write CallContext IsPersistent // - Write CallContext IsSuccess // - Write Account Nonce - // - Write TxAccessListAccount - // - Write TxAccessListAccount + // - Write TxAccessListAccount (Caller) + // - Write TxAccessListAccount (Callee) + // - Write TxAccessListAccount (Coinbase) for EIP-3651 // - Read Account CodeHash // - a TransferWithGasFeeGadget - rw_counter: Delta(8.expr() + transfer_with_gas_fee.rw_delta()), + rw_counter: Delta(9.expr() + transfer_with_gas_fee.rw_delta()), call_id: To(call_id.expr()), ..StepStateTransition::any() }); @@ -362,8 +396,9 @@ impl ExecutionGadget for BeginTxGadget { // - Write CallContext IsPersistent // - Write CallContext IsSuccess // - Write Account Nonce - // - Write TxAccessListAccount - // - Write TxAccessListAccount + // - Write TxAccessListAccount (Caller) + // - Write TxAccessListAccount (Callee) + // - Write TxAccessListAccount (Coinbase) for EIP-3651 // - Read Account CodeHash // - a TransferWithGasFeeGadget // - Write CallContext Depth @@ -379,7 +414,7 @@ impl ExecutionGadget for BeginTxGadget { // - Write CallContext IsRoot // - Write CallContext IsCreate // - Write CallContext CodeHash - rw_counter: Delta(21.expr() + transfer_with_gas_fee.rw_delta()), + rw_counter: Delta(22.expr() + transfer_with_gas_fee.rw_delta()), call_id: To(call_id.expr()), is_root: To(true.expr()), is_create: To(tx_is_create.expr()), @@ -406,6 +441,7 @@ impl ExecutionGadget for BeginTxGadget { tx_value, tx_call_data_length, tx_call_data_gas_cost, + tx_call_data_word_length, reversion_info, sufficient_gas_left, transfer_with_gas_fee, @@ -415,6 +451,8 @@ impl ExecutionGadget for BeginTxGadget { create, callee_not_exists, is_caller_callee_equal, + coinbase, + is_coinbase_warm, } } @@ -432,6 +470,8 @@ impl ExecutionGadget for BeginTxGadget { let mut rws = StepRws::new(block, step); rws.offset_add(7); + + let is_coinbase_warm = rws.next().tx_access_list_value_pair().1; let mut callee_code_hash = zero; if !is_precompiled(&tx.callee_address) && !tx.is_create { callee_code_hash = rws.next().account_value_pair().1; @@ -504,6 +544,8 @@ impl ExecutionGadget for BeginTxGadget { offset, Value::known(F::from(tx.call_data_gas_cost)), )?; + self.tx_call_data_word_length + .assign(region, offset, tx.call_data_length as u128 + 31)?; self.reversion_info.assign( region, offset, @@ -557,6 +599,23 @@ impl ExecutionGadget for BeginTxGadget { None, )?; + self.coinbase.assign( + region, + offset, + Value::known( + block + .context + .coinbase + .to_scalar() + .expect("unexpected Address -> Scalar conversion failure"), + ), + )?; + self.is_coinbase_warm.assign( + region, + offset, + Value::known(F::from(is_coinbase_warm as u64)), + )?; + Ok(()) } } @@ -614,6 +673,8 @@ mod test { .to(tx.to.unwrap()) .from(tx.from) .gas_price(tx.gas_price.unwrap()) + .max_fee_per_gas(tx.max_fee_per_gas.unwrap()) + .max_priority_fee_per_gas(tx.max_priority_fee_per_gas.unwrap()) .gas(tx.gas) .input(tx.input) .value(tx.value); @@ -635,6 +696,8 @@ mod test { .value(value) .gas(gas(&calldata)) .gas_price(gas_price) + .max_priority_fee_per_gas(gas_price) + .max_fee_per_gas(gas_price) .input(calldata.into()) .build(); diff --git a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs index 5461f36ffc..cb3eed29ab 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs @@ -11,9 +11,9 @@ use crate::{ }, math_gadget::{ AddWordsGadget, ConstantDivisionGadget, IsEqualGadget, MinMaxGadget, - MulWordByU64Gadget, + MinMaxWordGadget, MulWordByU64Gadget, }, - CachedRegion, Cell, + CachedRegion, Cell, Word, }, witness::{Block, Call, ExecStep, Transaction}, }, @@ -21,7 +21,8 @@ use crate::{ util::Expr, }; use bus_mapping::operation::Target; -use eth_types::{evm_types::MAX_REFUND_QUOTIENT_OF_GAS_USED, Field, ToScalar}; +use eth_types::{evm_types::MAX_REFUND_QUOTIENT_OF_GAS_USED, Field, ToLittleEndian, ToScalar}; +use gadgets::util::not; use halo2_proofs::{circuit::Value, plonk::Error}; use strum::EnumCount; @@ -32,16 +33,23 @@ pub(crate) struct EndTxGadget { max_refund: ConstantDivisionGadget, refund: Cell, effective_refund: MinMaxGadget, + min_max_effective_tip: MinMaxWordGadget, mul_gas_price_by_refund: MulWordByU64Gadget, tx_caller_address: Cell, gas_fee_refund: UpdateBalanceGadget, sub_gas_price_by_base_fee: AddWordsGadget, + sub_fee_cap_by_base_fee: AddWordsGadget, mul_effective_tip_by_gas_used: MulWordByU64Gadget, coinbase: Cell, coinbase_reward: UpdateBalanceGadget, current_cumulative_gas_used: Cell, is_first_tx: IsEqualGadget, is_persistent: Cell, + tx_gas_tip_cap: Word, + // taiko + mul_base_fee_by_gas_used: Option>, + treasury: Option>, + treasury_reward: Option>, } impl ExecutionGadget for EndTxGadget { @@ -56,7 +64,12 @@ impl ExecutionGadget for EndTxGadget { let [tx_gas, tx_caller_address] = [TxContextFieldTag::Gas, TxContextFieldTag::CallerAddress] .map(|field_tag| cb.tx_context(tx_id.expr(), field_tag, None)); - let tx_gas_price = cb.tx_context_as_word(tx_id.expr(), TxContextFieldTag::GasPrice, None); + let [tx_gas_price, tx_gas_tip_cap, tx_gas_fee_cap] = [ + TxContextFieldTag::GasPrice, + TxContextFieldTag::GasTipCap, + TxContextFieldTag::GasFeeCap, + ] + .map(|field_tag| cb.tx_context_as_word(tx_id.expr(), field_tag, None)); // Calculate effective gas to refund let gas_used = tx_gas.expr() - cb.curr.state.gas_left.expr(); @@ -82,20 +95,47 @@ impl ExecutionGadget for EndTxGadget { None, ); + let is_first_tx = IsEqualGadget::construct(cb, tx_id.expr(), 1.expr()); + // Add gas_used * effective_tip to coinbase's balance let coinbase = cb.query_cell(); + cb.block_lookup(BlockContextFieldTag::Coinbase.expr(), None, coinbase.expr()); let base_fee = cb.query_word_rlc(); - for (tag, value) in [ - (BlockContextFieldTag::Coinbase, coinbase.expr()), - (BlockContextFieldTag::BaseFee, base_fee.expr()), - ] { - cb.block_lookup(tag.expr(), None, value); + + if cb.is_taiko { + cb.condition(is_first_tx.expr(), |cb| { + cb.require_zero("base_fee is zero when tx is first tx", base_fee.expr()); + }); + cb.condition(not::expr(is_first_tx.expr()), |cb| { + cb.block_lookup(BlockContextFieldTag::BaseFee.expr(), None, base_fee.expr()); + }); + } else { + cb.block_lookup(BlockContextFieldTag::BaseFee.expr(), None, base_fee.expr()); } + + // https://eips.ethereum.org/EIPS/eip-1559 let effective_tip = cb.query_word_rlc(); + // effective_gas_price == base_fee + effective_tip let sub_gas_price_by_base_fee = - AddWordsGadget::construct(cb, [effective_tip.clone(), base_fee], tx_gas_price); + AddWordsGadget::construct(cb, [effective_tip.clone(), base_fee.clone()], tx_gas_price); let mul_effective_tip_by_gas_used = - MulWordByU64Gadget::construct(cb, effective_tip, gas_used.clone()); + MulWordByU64Gadget::construct(cb, effective_tip.clone(), gas_used.clone()); + + // effective_tip == min(gas_tip_cap, gas_fee_cap - base_fee) + let fee_cap_sub_base_fee = cb.query_word_rlc(); + let sub_fee_cap_by_base_fee = AddWordsGadget::construct( + cb, + [base_fee.clone(), fee_cap_sub_base_fee.clone()], + tx_gas_fee_cap, + ); + let min_max_effective_tip = + MinMaxWordGadget::construct(cb, &tx_gas_tip_cap, &fee_cap_sub_base_fee); + cb.require_equal( + "effective_tip == min(gas_tip_cap, gas_fee_cap - base_fee)", + effective_tip.expr(), + min_max_effective_tip.min(), + ); + let coinbase_reward = UpdateBalanceGadget::construct( cb, coinbase.expr(), @@ -103,6 +143,28 @@ impl ExecutionGadget for EndTxGadget { None, ); + let (mul_base_fee_by_gas_used, treasury, treasury_reward) = if cb.is_taiko { + let mul_base_fee_by_gas_used = + MulWordByU64Gadget::construct(cb, base_fee.clone(), gas_used.clone()); + // send base fee to treasury account + let treasury = cb.query_cell(); + cb.block_lookup(BlockContextFieldTag::Treasury.expr(), None, treasury.expr()); + + let treasury_reward = UpdateBalanceGadget::construct( + cb, + treasury.expr(), + vec![mul_base_fee_by_gas_used.product().clone()], + None, + ); + ( + Some(mul_base_fee_by_gas_used), + Some(treasury), + Some(treasury_reward), + ) + } else { + (None, None, None) + }; + // constrain tx receipt fields cb.tx_receipt_lookup( 1.expr(), @@ -117,8 +179,6 @@ impl ExecutionGadget for EndTxGadget { cb.curr.state.log_id.expr(), ); - let is_first_tx = IsEqualGadget::construct(cb, tx_id.expr(), 1.expr()); - let current_cumulative_gas_used = cb.query_cell(); cb.condition(is_first_tx.expr(), |cb| { cb.require_zero( @@ -143,6 +203,8 @@ impl ExecutionGadget for EndTxGadget { gas_used + current_cumulative_gas_used.expr(), ); + let begin_tx_rw_counter = if cb.is_taiko { 11.expr() } else { 10.expr() }; + cb.condition( cb.next.execution_state_selector([ExecutionState::BeginTx]), |cb| { @@ -154,17 +216,19 @@ impl ExecutionGadget for EndTxGadget { ); cb.require_step_state_transition(StepStateTransition { - rw_counter: Delta(10.expr() - is_first_tx.expr()), + rw_counter: Delta(begin_tx_rw_counter - is_first_tx.expr()), ..StepStateTransition::any() }); }, ); + let end_block_rw_counter = if cb.is_taiko { 10.expr() } else { 9.expr() }; + cb.condition( cb.next.execution_state_selector([ExecutionState::EndBlock]), |cb| { cb.require_step_state_transition(StepStateTransition { - rw_counter: Delta(9.expr() - is_first_tx.expr()), + rw_counter: Delta(end_block_rw_counter - is_first_tx.expr()), // We propagate call_id so that EndBlock can get the last tx_id // in order to count processed txs. call_id: Same, @@ -179,16 +243,22 @@ impl ExecutionGadget for EndTxGadget { max_refund, refund, effective_refund, + min_max_effective_tip, mul_gas_price_by_refund, tx_caller_address, gas_fee_refund, sub_gas_price_by_base_fee, + sub_fee_cap_by_base_fee, mul_effective_tip_by_gas_used, coinbase, coinbase_reward, current_cumulative_gas_used, is_first_tx, is_persistent, + tx_gas_tip_cap, + mul_base_fee_by_gas_used, + treasury, + treasury_reward, } } @@ -205,7 +275,6 @@ impl ExecutionGadget for EndTxGadget { let (refund, _) = block.get_rws(step, 2).tx_refund_value_pair(); let [(caller_balance, caller_balance_prev), (coinbase_balance, coinbase_balance_prev)] = [3, 4].map(|index| block.get_rws(step, index).account_value_pair()); - self.tx_id .assign(region, offset, Value::known(F::from(tx.id as u64)))?; self.tx_gas @@ -219,6 +288,26 @@ impl ExecutionGadget for EndTxGadget { F::from(max_refund as u64), F::from(refund), )?; + + let base_fee = if block.is_taiko() && tx.is_first_tx() { + 0.into() + } else { + block.context.base_fee + }; + self.tx_gas_tip_cap + .assign(region, offset, Some(tx.gas_tip_cap.to_le_bytes()))?; + self.sub_fee_cap_by_base_fee.assign( + region, + offset, + [base_fee, tx.gas_fee_cap - base_fee], + tx.gas_fee_cap, + )?; + self.min_max_effective_tip.assign( + region, + offset, + tx.gas_tip_cap, + tx.gas_fee_cap - base_fee, + )?; let effective_refund = refund.min(max_refund as u64); let gas_fee_refund = tx.gas_price * (effective_refund + step.gas_left.0); self.mul_gas_price_by_refund.assign( @@ -244,13 +333,14 @@ impl ExecutionGadget for EndTxGadget { vec![gas_fee_refund], caller_balance, )?; - let effective_tip = tx.gas_price - block.context.base_fee; + let effective_tip = tx.gas_price - base_fee; self.sub_gas_price_by_base_fee.assign( region, offset, - [effective_tip, block.context.base_fee], + [effective_tip, base_fee], tx.gas_price, )?; + self.mul_effective_tip_by_gas_used.assign( region, offset, @@ -276,7 +366,38 @@ impl ExecutionGadget for EndTxGadget { vec![effective_tip * gas_used], coinbase_balance, )?; - + if block.is_taiko() { + self.mul_base_fee_by_gas_used.as_ref().unwrap().assign( + region, + offset, + base_fee, + gas_used, + base_fee * gas_used, + )?; + self.treasury.as_ref().unwrap().assign( + region, + offset, + Value::known( + block + .protocol_instance + .as_ref() + .unwrap() + .meta_hash + .treasury + .to_scalar() + .expect("unexpected Address -> Scalar conversion failure"), + ), + )?; + let (treasury_balance, treasury_balance_prev) = + block.get_rws(step, 5).account_value_pair(); + self.treasury_reward.as_ref().unwrap().assign( + region, + offset, + treasury_balance_prev, + vec![base_fee * gas_used], + treasury_balance, + )?; + } let current_cumulative_gas_used: u64 = if tx.id == 1 { 0 } else { @@ -342,7 +463,7 @@ mod test { // Multiple txs test_ok( // Get the execution steps from the external tracer - TestContext::<2, 3>::new( + TestContext::<2, 3>::new_with_taiko( None, account_0_code_account_1_no_code(bytecode! { STOP }), |mut txs, accs| { diff --git a/zkevm-circuits/src/evm_circuit/execution/error_invalid_opcode.rs b/zkevm-circuits/src/evm_circuit/execution/error_invalid_opcode.rs index 868a830306..aa8c0ce1de 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_invalid_opcode.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_invalid_opcode.rs @@ -81,7 +81,10 @@ mod test { vec![0xf6], vec![0xfe], // Multiple invalid opcodes - vec![0x5c, 0x5e, 0x5f], + // TLOAD 0x5c eip-1153 + // MCOPY 0x5e eip-5656 + // PUSH0 ox5f eip-3855 + vec![], ]; } diff --git a/zkevm-circuits/src/evm_circuit/execution/push0.rs b/zkevm-circuits/src/evm_circuit/execution/push0.rs new file mode 100644 index 0000000000..c5f24cb07c --- /dev/null +++ b/zkevm-circuits/src/evm_circuit/execution/push0.rs @@ -0,0 +1,66 @@ +use crate::{ + evm_circuit::{ + execution::ExecutionGadget, + step::ExecutionState, + util::{ + common_gadget::SameContextGadget, + constraint_builder::{EVMConstraintBuilder, StepStateTransition, Transition::Delta}, + CachedRegion, Cell, + }, + witness::{Block, Call, ExecStep, Transaction}, + }, + util::Expr, +}; +use eth_types::{evm_types::OpcodeId, Field}; +use halo2_proofs::{circuit::Value, plonk::Error}; + +#[derive(Clone, Debug)] +pub(crate) struct DummyPush0Gadget { + same_context: SameContextGadget, + opcode: Cell, +} + +impl ExecutionGadget for DummyPush0Gadget { + const NAME: &'static str = "PUSH0"; + + const EXECUTION_STATE: ExecutionState = ExecutionState::PUSH0; + + fn configure(cb: &mut EVMConstraintBuilder) -> Self { + let opcode = cb.query_cell(); + // The dummy gadget only push the zero value on the stack(increase the stack pointer by 1) + cb.stack_push(0.expr()); + + // State transition + // `program_counter` needs to be increased by number of bytes pushed + 1 + let step_state_transition = StepStateTransition { + rw_counter: Delta(1.expr()), + program_counter: Delta(1.expr()), + stack_pointer: Delta((-1).expr()), + gas_left: Delta(-OpcodeId::PUSH0.constant_gas_cost().expr()), + ..Default::default() + }; + // SameContextGadget will increase the program_counter by 1 + let same_context = SameContextGadget::construct(cb, opcode.clone(), step_state_transition); + + Self { + same_context, + opcode, + } + } + + fn assign_exec_step( + &self, + region: &mut CachedRegion<'_, '_, F>, + offset: usize, + _: &Block, + _: &Transaction, + _: &Call, + step: &ExecStep, + ) -> Result<(), Error> { + self.same_context.assign_exec_step(region, offset, step)?; + let opcode = step.opcode().unwrap(); + self.opcode + .assign(region, offset, Value::known(F::from(opcode.as_u64())))?; + Ok(()) + } +} diff --git a/zkevm-circuits/src/evm_circuit/param.rs b/zkevm-circuits/src/evm_circuit/param.rs index e21530bb9c..f888a68734 100644 --- a/zkevm-circuits/src/evm_circuit/param.rs +++ b/zkevm-circuits/src/evm_circuit/param.rs @@ -1,4 +1,4 @@ -use super::table::Table; +use super::{table::Table, EvmCircuitParams}; use crate::evm_circuit::{step::ExecutionState, EvmCircuit}; use halo2_proofs::{ halo2curves::bn256::Fr, @@ -9,7 +9,7 @@ use std::collections::HashMap; // Step dimension pub(crate) const STEP_WIDTH: usize = 128; /// Step height -pub const MAX_STEP_HEIGHT: usize = 21; +pub const MAX_STEP_HEIGHT: usize = 23; /// The height of the state of a step, used by gates that connect two /// consecutive steps. We target 1, which is also convenient for padding with /// EndBlock steps. @@ -109,6 +109,7 @@ pub(crate) const N_BYTES_CALLDATASIZE: usize = N_BYTES_U64; lazy_static::lazy_static! { // Step slot height in evm circuit pub(crate) static ref EXECUTION_STATE_HEIGHT_MAP : HashMap = get_step_height_map(); + pub(crate) static ref EXECUTION_STATE_HEIGHT_MAP_WITH_TAIKO : HashMap = get_step_height_map_with_taiko(); } fn get_step_height_map() -> HashMap { let mut meta = ConstraintSystem::::default(); @@ -116,3 +117,10 @@ fn get_step_height_map() -> HashMap { circuit.0.execution.height_map } + +fn get_step_height_map_with_taiko() -> HashMap { + let mut meta = ConstraintSystem::::default(); + let circuit = EvmCircuit::configure_with_params(&mut meta, EvmCircuitParams { is_taiko: true }); + + circuit.0.execution.height_map +} diff --git a/zkevm-circuits/src/evm_circuit/step.rs b/zkevm-circuits/src/evm_circuit/step.rs index e73096d130..59cf6b4871 100644 --- a/zkevm-circuits/src/evm_circuit/step.rs +++ b/zkevm-circuits/src/evm_circuit/step.rs @@ -1,4 +1,7 @@ -use super::util::{CachedRegion, CellManager, CellType}; +use super::{ + param::EXECUTION_STATE_HEIGHT_MAP_WITH_TAIKO, + util::{CachedRegion, CellManager, CellType}, +}; use crate::{ evm_circuit::{ param::{EXECUTION_STATE_HEIGHT_MAP, MAX_STEP_HEIGHT, STEP_STATE_HEIGHT, STEP_WIDTH}, @@ -95,6 +98,7 @@ pub enum ExecutionState { MSIZE, GAS, JUMPDEST, + PUSH0, PUSH, // PUSH1, PUSH2, ..., PUSH32 DUP, // DUP1, DUP2, ..., DUP16 SWAP, // SWAP1, SWAP2, ..., SWAP16 @@ -198,6 +202,9 @@ impl From<&ExecStep> for ExecutionState { if op.is_dup() { return ExecutionState::DUP; } + if op.is_push0() { + return ExecutionState::PUSH0; + } if op.is_push() { return ExecutionState::PUSH; } @@ -417,6 +424,7 @@ impl ExecutionState { Self::MSIZE => vec![OpcodeId::MSIZE], Self::GAS => vec![OpcodeId::GAS], Self::JUMPDEST => vec![OpcodeId::JUMPDEST], + Self::PUSH0 => vec![OpcodeId::PUSH0], Self::PUSH => vec![ OpcodeId::PUSH1, OpcodeId::PUSH2, @@ -512,12 +520,16 @@ impl ExecutionState { .collect() } - pub fn get_step_height_option(&self) -> Option { - EXECUTION_STATE_HEIGHT_MAP.get(self).copied() + pub fn get_step_height_option(&self, is_taiko: bool) -> Option { + if is_taiko { + EXECUTION_STATE_HEIGHT_MAP_WITH_TAIKO.get(self).copied() + } else { + EXECUTION_STATE_HEIGHT_MAP.get(self).copied() + } } - pub fn get_step_height(&self) -> usize { - self.get_step_height_option() + pub fn get_step_height(&self, is_taiko: bool) -> usize { + self.get_step_height_option(is_taiko) .unwrap_or_else(|| panic!("Execution state unknown: {:?}", self)) } } diff --git a/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs b/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs index 8a714b64e0..e04954035a 100644 --- a/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs +++ b/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs @@ -279,6 +279,8 @@ pub(crate) struct EVMConstraintBuilder<'a, F> { conditions: Vec>, constraints_location: ConstraintLocation, stored_expressions: Vec>, + // in taiko context + pub(crate) is_taiko: bool, } impl<'a, F: Field> ConstrainBuilderCommon for EVMConstraintBuilder<'a, F> { @@ -300,6 +302,7 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> { next: Step, challenges: &'a Challenges>, execution_state: ExecutionState, + is_taiko: bool, ) -> Self { Self { max_degree: MAX_DEGREE, @@ -321,6 +324,7 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> { conditions: Vec::new(), constraints_location: ConstraintLocation::Step, stored_expressions: Vec::new(), + is_taiko, } } diff --git a/zkevm-circuits/src/evm_circuit/util/math_gadget.rs b/zkevm-circuits/src/evm_circuit/util/math_gadget.rs index fcaf39f0dd..7e440f971c 100644 --- a/zkevm-circuits/src/evm_circuit/util/math_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/math_gadget.rs @@ -15,6 +15,7 @@ mod is_zero; mod lt; mod lt_word; mod min_max; +mod min_max_word; mod modulo; mod mul_add_words; mod mul_add_words512; @@ -37,6 +38,7 @@ pub(crate) use is_zero::IsZeroGadget; pub(crate) use lt::LtGadget; pub(crate) use lt_word::LtWordGadget; pub(crate) use min_max::MinMaxGadget; +pub(crate) use min_max_word::MinMaxWordGadget; pub(crate) use modulo::ModGadget; pub(crate) use mul_add_words::MulAddWordsGadget; pub(crate) use mul_add_words512::MulAddWords512Gadget; diff --git a/zkevm-circuits/src/evm_circuit/util/math_gadget/min_max_word.rs b/zkevm-circuits/src/evm_circuit/util/math_gadget/min_max_word.rs new file mode 100644 index 0000000000..413eba708b --- /dev/null +++ b/zkevm-circuits/src/evm_circuit/util/math_gadget/min_max_word.rs @@ -0,0 +1,183 @@ +use crate::evm_circuit::util::{ + self, constraint_builder::EVMConstraintBuilder, math_gadget::*, select, CachedRegion, +}; +use eth_types::{Field, Word}; +use halo2_proofs::plonk::{Error, Expression}; + +/// Returns `rhs` when `lhs < rhs`, and returns `lhs` otherwise. +#[derive(Clone, Debug)] +pub struct MinMaxWordGadget { + lt: LtWordGadget, + min: Expression, + max: Expression, +} + +impl MinMaxWordGadget { + pub(crate) fn construct( + cb: &mut EVMConstraintBuilder, + lhs: &util::Word, + rhs: &util::Word, + ) -> Self { + let lt = LtWordGadget::construct(cb, lhs, rhs); + let max = select::expr(lt.expr(), rhs.expr(), lhs.expr()); + let min = select::expr(lt.expr(), lhs.expr(), rhs.expr()); + + Self { lt, min, max } + } + + pub(crate) fn min(&self) -> Expression { + self.min.clone() + } + + pub(crate) fn max(&self) -> Expression { + self.max.clone() + } + + pub(crate) fn assign( + &self, + region: &mut CachedRegion<'_, '_, F>, + offset: usize, + lhs: Word, + rhs: Word, + ) -> Result<(), Error> { + self.lt.assign(region, offset, lhs, rhs) + } +} + +#[cfg(test)] +mod tests { + use super::{test_util::*, *}; + use crate::evm_circuit::util::constraint_builder::ConstrainBuilderCommon; + use eth_types::{ToLittleEndian, Word}; + use halo2_proofs::{halo2curves::bn256::Fr, plonk::Error}; + + #[derive(Clone)] + /// MinMaxTestContainer: require(min(a, b) == (a if MIN_IS_A else b)) + struct MinMaxWordTestContainer { + minmax_word_gadget: MinMaxWordGadget, + a: util::Word, + b: util::Word, + } + + impl MathGadgetContainer + for MinMaxWordTestContainer + { + fn configure_gadget_container(cb: &mut EVMConstraintBuilder) -> Self { + let a = cb.query_word_rlc(); + let b = cb.query_word_rlc(); + let minmax_word_gadget = MinMaxWordGadget::::construct(cb, &a, &b); + + if MIN_IS_A { + cb.require_equal("min == a", minmax_word_gadget.min(), a.expr()); + cb.require_equal("max == b", minmax_word_gadget.max(), b.expr()); + } else { + cb.require_equal("min == b", minmax_word_gadget.min(), b.expr()); + cb.require_equal("max == a", minmax_word_gadget.max(), a.expr()); + } + + MinMaxWordTestContainer { + minmax_word_gadget, + a, + b, + } + } + + fn assign_gadget_container( + &self, + witnesses: &[Word], + region: &mut CachedRegion<'_, '_, F>, + ) -> Result<(), Error> { + let a = witnesses[0]; + let b = witnesses[1]; + let offset = 0; + + self.a.assign(region, offset, Some(a.to_le_bytes()))?; + self.b.assign(region, offset, Some(b.to_le_bytes()))?; + self.minmax_word_gadget.assign(region, offset, a, b)?; + + Ok(()) + } + } + + #[test] + fn test_minmax_eq() { + // a == b + try_test!( + MinMaxWordTestContainer, + vec![Word::from(0), Word::from(0)], + true, + ); + try_test!( + MinMaxWordTestContainer, + vec![Word::from(5), Word::from(5)], + true, + ); + try_test!( + MinMaxWordTestContainer, + vec![WORD_LOW_MAX, WORD_LOW_MAX], + true, + ); + } + + #[test] + fn test_minmax_expect_min_a() { + // min == a, max == b + try_test!( + MinMaxWordTestContainer, + vec![Word::from(0), Word::from(1)], + true, + ); + try_test!( + MinMaxWordTestContainer, + vec![Word::from(3), Word::from(5)], + true, + ); + try_test!( + MinMaxWordTestContainer, + vec![WORD_LOW_MAX, WORD_LOW_MAX], + true, + ); + } + + #[test] + fn test_minmax_unexpect_min_a() { + // min == b, max == a + try_test!( + MinMaxWordTestContainer, + vec![Word::from(1), Word::from(0)], + false, + ); + try_test!( + MinMaxWordTestContainer, + vec![Word::from(256), Word::from(3)], + false, + ); + try_test!( + MinMaxWordTestContainer, + vec![WORD_LOW_MAX, Word::from(123456)], + false, + ); + } + + #[test] + fn test_minmax_expect_min_b() { + // min == a, max == b + try_test!( + MinMaxWordTestContainer, + vec![Word::from(1), Word::from(0)], + true, + ); + + try_test!( + MinMaxWordTestContainer, + vec![Word::from(777), Word::from(44)], + true, + ); + + try_test!( + MinMaxWordTestContainer, + vec![WORD_LOW_MAX+1, WORD_LOW_MAX], + true, + ); + } +} diff --git a/zkevm-circuits/src/evm_circuit/util/math_gadget/test_util.rs b/zkevm-circuits/src/evm_circuit/util/math_gadget/test_util.rs index 0541bc0fc1..9d850630c8 100644 --- a/zkevm-circuits/src/evm_circuit/util/math_gadget/test_util.rs +++ b/zkevm-circuits/src/evm_circuit/util/math_gadget/test_util.rs @@ -131,6 +131,7 @@ impl> Circuit for UnitTestMathGadgetBaseC step_next, &challenges_exprs, ExecutionState::STOP, + false, ); let math_gadget_container = G::configure_gadget_container(&mut cb); let (constraints, stored_expressions, _) = cb.build(); diff --git a/zkevm-circuits/src/pi_circuit.rs b/zkevm-circuits/src/pi_circuit.rs index a7a22be423..2e9edae155 100644 --- a/zkevm-circuits/src/pi_circuit.rs +++ b/zkevm-circuits/src/pi_circuit.rs @@ -3,8 +3,11 @@ mod param; #[cfg(any(feature = "test", test, feature = "test-circuits"))] mod dev; -#[cfg(any(feature = "test", test))] -mod test; + +// FIXME: ignore unused long-time running tests +// #[cfg(any(feature = "test", test))] +// #[cfg(any(feature = "test", test))] +// mod test; use eth_types::{ geth_types::{BlockConstants, Transaction}, @@ -42,7 +45,7 @@ pub struct BlockValues { gas_limit: u64, number: u64, timestamp: u64, - difficulty: Word, + mix_hash: H256, base_fee: Word, // NOTE: BaseFee was added by EIP-1559 and is ignored in legacy headers. chain_id: u64, history_hashes: Vec, @@ -122,7 +125,7 @@ impl PublicData { gas_limit: self.block_constants.gas_limit.as_u64(), number: self.block_constants.number.as_u64(), timestamp: self.block_constants.timestamp.as_u64(), - difficulty: self.block_constants.difficulty, + mix_hash: self.block_constants.mix_hash, base_fee: self.block_constants.base_fee, chain_id: self.chain_id.as_u64(), history_hashes, @@ -923,21 +926,23 @@ impl PiCircuitConfig { raw_pi_vals[offset] = timestamp; offset += 1; - // difficulty - let difficulty = rlc(block_values.difficulty.to_le_bytes(), randomness); + let mut mix_hash_bytes = block_values.mix_hash.to_fixed_bytes(); + mix_hash_bytes.reverse(); + // mix hash + let mix_hash = rlc(mix_hash_bytes, randomness); region.assign_advice( - || "difficulty", + || "mix_hash", self.block_table.value, offset, - || Value::known(difficulty), + || Value::known(mix_hash), )?; region.assign_advice( - || "difficulty", + || "mix_hash", self.raw_public_inputs, offset, - || Value::known(difficulty), + || Value::known(mix_hash), )?; - raw_pi_vals[offset] = difficulty; + raw_pi_vals[offset] = mix_hash; offset += 1; // base_fee @@ -1161,7 +1166,7 @@ impl SubCircuit for PiCircuit { coinbase: block.context.coinbase, timestamp: block.context.timestamp, number: block.context.number.as_u64().into(), - difficulty: block.context.difficulty, + mix_hash: block.context.mix_hash, gas_limit: block.context.gas_limit.into(), base_fee: block.context.base_fee, }, @@ -1484,8 +1489,10 @@ fn raw_public_inputs_col( // timestamp result[offset] = F::from(block.timestamp); offset += 1; - // difficulty - result[offset] = rlc(block.difficulty.to_le_bytes(), randomness); + // mix hash + let mut mix_hash_bytes = block.mix_hash.to_fixed_bytes(); + mix_hash_bytes.reverse(); + result[offset] = rlc(mix_hash_bytes, randomness); offset += 1; // base_fee result[offset] = rlc(block.base_fee.to_le_bytes(), randomness); diff --git a/zkevm-circuits/src/root_circuit.rs b/zkevm-circuits/src/root_circuit.rs index e1bfa9b25c..9370a28179 100644 --- a/zkevm-circuits/src/root_circuit.rs +++ b/zkevm-circuits/src/root_circuit.rs @@ -17,8 +17,9 @@ pub mod taiko_aggregation; pub use taiko_aggregation::TaikoAggregationCircuit; -#[cfg(any(feature = "test", test))] -mod test; +// FIXME: ignore unused long-time running tests +// #[cfg(any(feature = "test", test))] +// mod test; #[cfg(any(feature = "test", test, feature = "test-circuits"))] pub use self::RootCircuit as TestRootCircuit; diff --git a/zkevm-circuits/src/super_circuit.rs b/zkevm-circuits/src/super_circuit.rs index cb5deac7f7..32734b4ea7 100644 --- a/zkevm-circuits/src/super_circuit.rs +++ b/zkevm-circuits/src/super_circuit.rs @@ -50,8 +50,9 @@ //! - [x] Tx Circuit //! - [ ] MPT Circuit -#[cfg(any(feature = "test", test))] -pub(crate) mod test; +// FIXME: ignore unused long-time running tests +// #[cfg(any(feature = "test", test))] +// pub(crate) mod test; use crate::{ bytecode_circuit::circuit::{ @@ -204,6 +205,7 @@ impl SubCircuitConfig for SuperCircuitConfig { copy_table, keccak_table, exp_table, + is_taiko: false, }, ); diff --git a/zkevm-circuits/src/table.rs b/zkevm-circuits/src/table.rs index 223fe24d5d..314268818b 100644 --- a/zkevm-circuits/src/table.rs +++ b/zkevm-circuits/src/table.rs @@ -48,6 +48,7 @@ pub(crate) mod rw_table; pub(crate) mod tx_table; pub(crate) use block_table::{BlockContextFieldTag, BlockTable}; +pub(crate) use byte_table::ByteTable; pub(crate) use bytecode_table::{BytecodeFieldTag, BytecodeTable}; pub(crate) use copy_table::CopyTable; pub(crate) use exp_table::ExpTable; diff --git a/zkevm-circuits/src/table/block_table.rs b/zkevm-circuits/src/table/block_table.rs index 443e993673..4c58b76377 100644 --- a/zkevm-circuits/src/table/block_table.rs +++ b/zkevm-circuits/src/table/block_table.rs @@ -21,6 +21,8 @@ pub enum BlockContextFieldTag { /// Chain ID field. Although this is not a field in the block header, we /// add it here for convenience. ChainId, + /// Treasury accounts for receiving block base fee + Treasury, } impl_expr!(BlockContextFieldTag); diff --git a/zkevm-circuits/src/table/pi_table.rs b/zkevm-circuits/src/table/pi_table.rs index b772160eb9..15f8ef1e30 100644 --- a/zkevm-circuits/src/table/pi_table.rs +++ b/zkevm-circuits/src/table/pi_table.rs @@ -1,4 +1,5 @@ -use crate::witness::ProtocolInstance; +use crate::witness::protocol_instance_table_assignments; +use bus_mapping::circuit_input_builder::ProtocolInstance; use super::*; @@ -40,10 +41,10 @@ impl PiTable { || "pi table", |mut region| { let randomness = challenges.evm_word(); - for (offset, [tag, value]) in protocol_instance - .table_assignments(randomness) - .into_iter() - .enumerate() + for (offset, [tag, value]) in + protocol_instance_table_assignments(protocol_instance, randomness) + .into_iter() + .enumerate() { region.assign_fixed(|| "tag", self.tag, offset, || tag)?; region.assign_advice(|| "value", self.value, offset, || value)?; diff --git a/zkevm-circuits/src/table/tx_table.rs b/zkevm-circuits/src/table/tx_table.rs index 9d7cb74c91..5ec120fbee 100644 --- a/zkevm-circuits/src/table/tx_table.rs +++ b/zkevm-circuits/src/table/tx_table.rs @@ -12,6 +12,10 @@ pub enum TxFieldTag { Gas, /// GasPrice GasPrice, + /// GasTipCap + GasTipCap, + /// GasFeeCap + GasFeeCap, /// CallerAddress CallerAddress, /// CalleeAddress diff --git a/zkevm-circuits/src/taiko_pi_circuit.rs b/zkevm-circuits/src/taiko_pi_circuit.rs index 125e35c1ff..824a5eb761 100644 --- a/zkevm-circuits/src/taiko_pi_circuit.rs +++ b/zkevm-circuits/src/taiko_pi_circuit.rs @@ -116,34 +116,39 @@ impl PublicData { } fn default() -> Self { - Self::new::(&witness::Block::default()) + let block = witness::Block { + protocol_instance: Some(Default::default()), + ..Default::default() + }; + Self::new::(&block) } /// create PublicData from block and taiko pub fn new(block: &witness::Block) -> Self { - use witness::left_shift; - let field9 = left_shift(block.protocol_instance.prover, 96) - + left_shift(block.protocol_instance.parent_gas_used as u64, 64) - + left_shift(block.protocol_instance.gas_used as u64, 32); - - let field10 = left_shift(block.protocol_instance.block_max_gas_limit, 192) - + left_shift(block.protocol_instance.max_transactions_per_block, 128) - + left_shift(block.protocol_instance.max_bytes_per_tx_list, 64); + use bus_mapping::circuit_input_builder::left_shift; + let protocol_instance = block.protocol_instance.clone().unwrap(); + let field9 = left_shift(protocol_instance.prover, 96) + + left_shift(protocol_instance.parent_gas_used as u64, 64) + + left_shift(protocol_instance.gas_used as u64, 32); + + let field10 = left_shift(protocol_instance.block_max_gas_limit, 192) + + left_shift(protocol_instance.max_transactions_per_block, 128) + + left_shift(protocol_instance.max_bytes_per_tx_list, 64); PublicData { - l1_signal_service: block.protocol_instance.l1_signal_service.to_word(), - l2_signal_service: block.protocol_instance.l2_signal_service.to_word(), - l2_contract: block.protocol_instance.l2_contract.to_word(), - meta_hash: block.protocol_instance.meta_hash.hash().to_word(), - block_hash: block.protocol_instance.block_hash.to_word(), - parent_hash: block.protocol_instance.parent_hash.to_word(), - signal_root: block.protocol_instance.signal_root.to_word(), - graffiti: block.protocol_instance.graffiti.to_word(), - prover: block.protocol_instance.prover, - parent_gas_used: block.protocol_instance.parent_gas_used, - gas_used: block.protocol_instance.gas_used, - block_max_gas_limit: block.protocol_instance.block_max_gas_limit, - max_transactions_per_block: block.protocol_instance.max_transactions_per_block, - max_bytes_per_tx_list: block.protocol_instance.max_bytes_per_tx_list, + l1_signal_service: protocol_instance.l1_signal_service.to_word(), + l2_signal_service: protocol_instance.l2_signal_service.to_word(), + l2_contract: protocol_instance.l2_contract.to_word(), + meta_hash: protocol_instance.meta_hash.hash().to_word(), + block_hash: protocol_instance.block_hash.to_word(), + parent_hash: protocol_instance.parent_hash.to_word(), + signal_root: protocol_instance.signal_root.to_word(), + graffiti: protocol_instance.graffiti.to_word(), + prover: protocol_instance.prover, + parent_gas_used: protocol_instance.parent_gas_used, + gas_used: protocol_instance.gas_used, + block_max_gas_limit: protocol_instance.block_max_gas_limit, + max_transactions_per_block: protocol_instance.max_transactions_per_block, + max_bytes_per_tx_list: protocol_instance.max_bytes_per_tx_list, field9, field10, block_context: block.context.clone(), @@ -757,12 +762,15 @@ mod taiko_pi_circuit_test { #[test] fn test_verify() { - let mut block = witness::Block::::default(); + let mut block = witness::Block:: { + protocol_instance: Some(Default::default()), + ..Default::default() + }; block.eth_block.parent_hash = *OMMERS_HASH; block.eth_block.hash = Some(*OMMERS_HASH); - block.protocol_instance.block_hash = *OMMERS_HASH; - block.protocol_instance.parent_hash = *OMMERS_HASH; + block.protocol_instance.as_mut().unwrap().block_hash = *OMMERS_HASH; + block.protocol_instance.as_mut().unwrap().parent_hash = *OMMERS_HASH; block.context.history_hashes = vec![OMMERS_HASH.to_word()]; block.context.block_hash = OMMERS_HASH.to_word(); block.context.number = 300.into(); diff --git a/zkevm-circuits/src/taiko_super_circuit.rs b/zkevm-circuits/src/taiko_super_circuit.rs index 650700be56..6e14f4b70c 100644 --- a/zkevm-circuits/src/taiko_super_circuit.rs +++ b/zkevm-circuits/src/taiko_super_circuit.rs @@ -6,13 +6,17 @@ pub mod test; use crate::{ anchor_tx_circuit::{AnchorTxCircuit, AnchorTxCircuitConfig, AnchorTxCircuitConfigArgs}, - table::{byte_table::ByteTable, BlockTable, KeccakTable, PiTable, TxTable}, + evm_circuit::{EvmCircuit, EvmCircuitConfig, EvmCircuitConfigArgs}, + table::{ + BlockTable, ByteTable, BytecodeTable, CopyTable, ExpTable, KeccakTable, PiTable, RwTable, + TxTable, + }, taiko_pi_circuit::{TaikoPiCircuit, TaikoPiCircuitConfig, TaikoPiCircuitConfigArgs}, util::{log2_ceil, Challenges, SubCircuit, SubCircuitConfig}, - witness::{block_convert, Block, ProtocolInstance}, + witness::{block_convert, Block}, }; use bus_mapping::{ - circuit_input_builder::{CircuitInputBuilder, CircuitsParams}, + circuit_input_builder::{CircuitInputBuilder, CircuitsParams, ProtocolInstance}, mock::BlockData, }; use eth_types::{geth_types::GethData, Field}; @@ -28,12 +32,17 @@ use snark_verifier_sdk::CircuitExt; #[derive(Clone)] pub struct SuperCircuitConfig { tx_table: TxTable, + rw_table: RwTable, + bytecode_table: BytecodeTable, pi_table: PiTable, keccak_table: KeccakTable, block_table: BlockTable, byte_table: ByteTable, + copy_table: CopyTable, + exp_table: ExpTable, pi_circuit: TaikoPiCircuitConfig, anchor_tx_circuit: AnchorTxCircuitConfig, + evm_circuit: EvmCircuitConfig, } /// Circuit configuration arguments @@ -51,10 +60,15 @@ impl SubCircuitConfig for SuperCircuitConfig { Self::ConfigArgs { challenges }: Self::ConfigArgs, ) -> Self { let tx_table = TxTable::construct(meta); + let rw_table = RwTable::construct(meta); + let bytecode_table = BytecodeTable::construct(meta); let pi_table = PiTable::construct(meta); let block_table = BlockTable::construct(meta); let keccak_table = KeccakTable::construct(meta); let byte_table = ByteTable::construct(meta); + let q_copy_table = meta.fixed_column(); + let copy_table = CopyTable::construct(meta, q_copy_table); + let exp_table = ExpTable::construct(meta); let pi_circuit = TaikoPiCircuitConfig::new( meta, @@ -72,18 +86,38 @@ impl SubCircuitConfig for SuperCircuitConfig { tx_table: tx_table.clone(), pi_table: pi_table.clone(), byte_table: byte_table.clone(), + challenges: challenges.clone(), + }, + ); + + let evm_circuit = EvmCircuitConfig::new( + meta, + EvmCircuitConfigArgs { challenges, + tx_table: tx_table.clone(), + rw_table, + bytecode_table: bytecode_table.clone(), + block_table: block_table.clone(), + copy_table, + keccak_table: keccak_table.clone(), + exp_table, + is_taiko: true, }, ); Self { tx_table, + rw_table, + bytecode_table, + copy_table, + exp_table, pi_table, pi_circuit, block_table, keccak_table, byte_table, anchor_tx_circuit, + evm_circuit, } } } @@ -95,6 +129,8 @@ pub struct SuperCircuit { pub pi_circuit: TaikoPiCircuit, /// Anchor Transaction Circuit pub anchor_tx_circuit: AnchorTxCircuit, + /// EVM Circuit + pub evm_circuit: EvmCircuit, /// Block witness pub block: Block, } @@ -122,10 +158,12 @@ impl SubCircuit for SuperCircuit { fn new_from_block(block: &Block) -> Self { let pi_circuit = TaikoPiCircuit::new_from_block(block); let anchor_tx_circuit = AnchorTxCircuit::new_from_block(block); + let evm_circuit = EvmCircuit::new_from_block(block); SuperCircuit::<_> { pi_circuit, anchor_tx_circuit, + evm_circuit, block: block.clone(), } } @@ -160,6 +198,8 @@ impl SubCircuit for SuperCircuit { .synthesize_sub(&config.pi_circuit, challenges, layouter)?; self.anchor_tx_circuit .synthesize_sub(&config.anchor_tx_circuit, challenges, layouter)?; + self.evm_circuit + .synthesize_sub(&config.evm_circuit, challenges, layouter)?; Ok(()) } } @@ -206,13 +246,44 @@ impl Circuit for SuperCircuit { .load(&mut layouter, &self.block.context, randomness)?; config.keccak_table.dev_load( &mut layouter, - vec![&self.pi_circuit.public_data.rpi_bytes()], + self.block + .sha3_inputs + .iter() + .chain(std::iter::once(&self.pi_circuit.public_data.rpi_bytes())), &challenges, )?; config.byte_table.load(&mut layouter)?; + config.pi_table.load( + &mut layouter, + self.block.protocol_instance.as_ref().unwrap(), + &challenges, + )?; + // rw_table, + // bytecode_table, + // copy_table, + // exp_table, + + config.tx_table.load( + &mut layouter, + &self.block.txs, + self.block.circuits_params.max_txs, + self.block.circuits_params.max_calldata, + &challenges, + )?; + self.block.rws.check_rw_counter_sanity(); + config.rw_table.load( + &mut layouter, + &self.block.rws.table_assignments(), + self.block.circuits_params.max_rws, + challenges.evm_word(), + )?; + config + .bytecode_table + .load(&mut layouter, self.block.bytecodes.values(), &challenges)?; config - .pi_table - .load(&mut layouter, &self.block.protocol_instance, &challenges)?; + .copy_table + .load(&mut layouter, &self.block, &challenges)?; + config.exp_table.load(&mut layouter, &self.block)?; self.synthesize_sub(&config, &challenges, &mut layouter) } } @@ -227,16 +298,19 @@ impl SuperCircuit { pub fn build( geth_data: GethData, circuits_params: CircuitsParams, - protocol_instance: ProtocolInstance, + mut protocol_instance: ProtocolInstance, ) -> Result<(u32, Self, Vec>, CircuitInputBuilder), bus_mapping::Error> { let block_data = BlockData::new_from_geth_data_with_params(geth_data.clone(), circuits_params); let mut builder = block_data.new_circuit_input_builder(); + protocol_instance.block_hash = geth_data.eth_block.hash.unwrap(); + protocol_instance.parent_hash = geth_data.eth_block.parent_hash; + builder.block.protocol_instance = Some(protocol_instance); builder .handle_block(&geth_data.eth_block, &geth_data.geth_traces) .expect("could not handle block tx"); - let ret = Self::build_from_circuit_input_builder(&builder, protocol_instance)?; + let ret = Self::build_from_circuit_input_builder(&builder)?; Ok((ret.0, ret.1, ret.2, builder)) } @@ -247,12 +321,8 @@ impl SuperCircuit { /// the Public Inputs needed. pub fn build_from_circuit_input_builder( builder: &CircuitInputBuilder, - protocol_instance: ProtocolInstance, ) -> Result<(u32, Self, Vec>), bus_mapping::Error> { - let mut block = block_convert(&builder.block, &builder.code_db).unwrap(); - block.protocol_instance = protocol_instance; - block.protocol_instance.block_hash = block.eth_block.hash.unwrap(); - block.protocol_instance.parent_hash = block.eth_block.parent_hash; + let block = block_convert(&builder.block, &builder.code_db).unwrap(); let (_, rows_needed) = Self::min_num_rows_block(&block); let k = log2_ceil(Self::unusable_rows() + rows_needed); log::debug!("super circuit uses k = {}", k); diff --git a/zkevm-circuits/src/taiko_super_circuit/test.rs b/zkevm-circuits/src/taiko_super_circuit/test.rs index db1583294d..f661af7a4e 100644 --- a/zkevm-circuits/src/taiko_super_circuit/test.rs +++ b/zkevm-circuits/src/taiko_super_circuit/test.rs @@ -1,13 +1,13 @@ #![allow(unused_imports)] pub use super::*; -use crate::{ - anchor_tx_circuit::{add_anchor_accounts, add_anchor_tx, sign_tx}, - witness::MetaHash, -}; +use bus_mapping::circuit_input_builder::MetaHash; use ethers_signers::{LocalWallet, Signer}; use halo2_proofs::{dev::MockProver, halo2curves::bn256::Fr}; use log::error; -use mock::{TestContext, MOCK_CHAIN_ID}; +use mock::{ + TestContext, MOCK_ANCHOR_GAS_LIMIT, MOCK_ANCHOR_L1_HASH, MOCK_ANCHOR_L1_HIGHT, + MOCK_ANCHOR_PARENT_GAS_USED, MOCK_ANCHOR_SIGNAL_ROOT, MOCK_CHAIN_ID, +}; use rand::SeedableRng; use rand_chacha::ChaCha20Rng; use std::str::FromStr; @@ -41,7 +41,7 @@ fn test_super_circuit( } /// build a block with anchor tx -pub fn block_1tx(protocol_instance: &ProtocolInstance) -> GethData { +pub fn block_1tx() -> GethData { let mut rng = ChaCha20Rng::seed_from_u64(2); let chain_id = (*MOCK_CHAIN_ID).as_u64(); @@ -56,39 +56,25 @@ pub fn block_1tx(protocol_instance: &ProtocolInstance) -> GethData { let addr_a = wallet_a.address(); let addr_b = address!("0x000000000000000000000000000000000000BBBB"); - let mut block: GethData = TestContext::<4, 2>::new( + let mut block: GethData = TestContext::<2, 1>::new_with_taiko( None, |accs| { - add_anchor_accounts( - accs, - |accs| { - accs[2] - .address(addr_b) - .balance(Word::from(1u64 << 20)) - .code(bytecode); - accs[3].address(addr_a).balance(Word::from(1u64 << 20)); - }, - protocol_instance, - ); + accs[0] + .address(addr_b) + .balance(Word::from(1u64 << 20)) + .code(bytecode); + accs[1].address(addr_a).balance(Word::from(1u64 << 20)); }, - |txs, accs| { - add_anchor_tx( - txs, - accs, - |mut txs, accs| { - txs[1] - .from(accs[3].address) - .to(accs[2].address) - .nonce(0) - .gas(Word::from(1_000_000u64)); - let geth_tx: eth_types::Transaction = txs[1].clone().into(); - let req: ethers_core::types::TransactionRequest = (&geth_tx).into(); - let sig = wallet_a.sign_transaction_sync(&req.chain_id(chain_id).into()); - txs[1].sig_data((sig.v, sig.r, sig.s)); - }, - sign_tx, - protocol_instance, - ); + |mut txs, accs| { + txs[0] + .from(accs[1].address) + .to(accs[0].address) + .nonce(0) + .gas(Word::from(1_000_000u64)); + let geth_tx: eth_types::Transaction = txs[0].clone().into(); + let req: ethers_core::types::TransactionRequest = (&geth_tx).into(); + let sig = wallet_a.sign_transaction_sync(&req.chain_id(chain_id).into()); + txs[0].sig_data((sig.v, sig.r, sig.s)); }, |block, _tx| block.number(0xcafeu64), ) @@ -98,7 +84,7 @@ pub fn block_1tx(protocol_instance: &ProtocolInstance) -> GethData { block } -fn block_2tx(protocol_instance: &ProtocolInstance) -> GethData { +fn block_2tx() -> GethData { let mut rng = ChaCha20Rng::seed_from_u64(2); let chain_id = (*MOCK_CHAIN_ID).as_u64(); @@ -113,48 +99,34 @@ fn block_2tx(protocol_instance: &ProtocolInstance) -> GethData { let addr_a = wallet_a.address(); let addr_b = address!("0x000000000000000000000000000000000000BBBB"); - let mut block: GethData = TestContext::<4, 3>::new( + let mut block: GethData = TestContext::<2, 2>::new_with_taiko( None, |accs| { - add_anchor_accounts( - accs, - |accs| { - accs[2] - .address(addr_b) - .balance(Word::from(1u64 << 20)) - .code(bytecode); - accs[3].address(addr_a).balance(Word::from(1u64 << 20)); - }, - protocol_instance, - ); + accs[0] + .address(addr_b) + .balance(Word::from(1u64 << 20)) + .code(bytecode); + accs[1].address(addr_a).balance(Word::from(1u64 << 20)); }, - |txs, accs| { - add_anchor_tx( - txs, - accs, - |mut txs, accs| { - txs[1] - .from(accs[3].address) - .to(accs[2].address) - .nonce(0) - .gas(Word::from(1_000_000u64)); - let geth_tx: eth_types::Transaction = txs[1].clone().into(); - let req: ethers_core::types::TransactionRequest = (&geth_tx).into(); - let sig = wallet_a.sign_transaction_sync(&req.chain_id(chain_id).into()); - txs[1].sig_data((sig.v, sig.r, sig.s)); - txs[2] - .from(accs[3].address) - .to(accs[2].address) - .nonce(1) - .gas(Word::from(1_000_000u64)); - let geth_tx: eth_types::Transaction = txs[2].clone().into(); - let req: ethers_core::types::TransactionRequest = (&geth_tx).into(); - let sig = wallet_a.sign_transaction_sync(&req.chain_id(chain_id).into()); - txs[2].sig_data((sig.v, sig.r, sig.s)); - }, - sign_tx, - protocol_instance, - ); + |mut txs, accs| { + txs[0] + .from(accs[1].address) + .to(accs[0].address) + .nonce(0) + .gas(Word::from(1_000_000u64)); + let geth_tx: eth_types::Transaction = txs[0].clone().into(); + let req: ethers_core::types::TransactionRequest = (&geth_tx).into(); + let sig = wallet_a.sign_transaction_sync(&req.chain_id(chain_id).into()); + txs[0].sig_data((sig.v, sig.r, sig.s)); + txs[1] + .from(accs[1].address) + .to(accs[0].address) + .nonce(1) + .gas(Word::from(1_000_000u64)); + let geth_tx: eth_types::Transaction = txs[1].clone().into(); + let req: ethers_core::types::TransactionRequest = (&geth_tx).into(); + let sig = wallet_a.sign_transaction_sync(&req.chain_id(chain_id).into()); + txs[1].sig_data((sig.v, sig.r, sig.s)); }, |block, _tx| block.number(0xcafeu64), ) @@ -175,30 +147,9 @@ fn serial_test_super_circuit_1tx_1max_tx() { let parent_hash = Hash::from_str("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49346") .unwrap(); - let protocol_instance = ProtocolInstance { - anchor_gas_limit: 150000, - block_hash, - parent_hash, - meta_hash: MetaHash { - l1_hash: block_hash, - l1_height: 20, - ..Default::default() - }, - signal_root: block_hash, - parent_gas_used: 2000, - ..Default::default() - }; - let mut block = block_1tx(&protocol_instance); - let circuits_params = CircuitsParams { - max_txs: 2, - max_calldata: 200, - max_rws: 256, - max_copy_rows: 256, - max_exp_steps: 256, - max_bytecode: 512, - max_evm_rows: 0, - max_keccak_rows: 0, - }; + let protocol_instance = ProtocolInstance::default(); + let mut block = block_1tx(); + let circuits_params = CircuitsParams::default(); block.eth_block.hash = Some(block_hash); block.eth_block.parent_hash = parent_hash; block.history_hashes = vec![block.eth_block.parent_hash.to_word()]; @@ -207,11 +158,8 @@ fn serial_test_super_circuit_1tx_1max_tx() { #[ignore] #[test] fn taiko_serial_test_super_circuit_1tx_3max_tx() { - let protocol_instance = ProtocolInstance { - anchor_gas_limit: 150000, - ..Default::default() - }; - let block = block_1tx(&protocol_instance); + let protocol_instance = ProtocolInstance::default(); + let block = block_1tx(); let circuits_params = CircuitsParams { max_txs: 3, max_calldata: 200, @@ -227,11 +175,8 @@ fn taiko_serial_test_super_circuit_1tx_3max_tx() { #[ignore] #[test] fn taiko_serial_test_super_circuit_2tx_3max_tx() { - let protocol_instance = ProtocolInstance { - anchor_gas_limit: 150000, - ..Default::default() - }; - let block = block_2tx(&protocol_instance); + let protocol_instance = ProtocolInstance::default(); + let block = block_2tx(); let circuits_params = CircuitsParams { max_txs: 3, max_calldata: 200, diff --git a/zkevm-circuits/src/test_util.rs b/zkevm-circuits/src/test_util.rs index 99ba2dfd56..2b026640a4 100644 --- a/zkevm-circuits/src/test_util.rs +++ b/zkevm-circuits/src/test_util.rs @@ -6,7 +6,10 @@ use crate::{ util::SubCircuit, witness::{Block, Rw}, }; -use bus_mapping::{circuit_input_builder::CircuitsParams, mock::BlockData}; +use bus_mapping::{ + circuit_input_builder::{CircuitsParams, ProtocolInstance}, + mock::BlockData, +}; use eth_types::geth_types::GethData; use std::cmp; @@ -190,9 +193,14 @@ impl CircuitTestBuilder { let block: Block = if self.block.is_some() { self.block.unwrap() } else if self.test_ctx.is_some() { - let block: GethData = self.test_ctx.unwrap().into(); + let test_ctx = self.test_ctx.unwrap(); + let is_taiko = test_ctx.is_taiko; + let block: GethData = test_ctx.into(); let mut builder = BlockData::new_from_geth_data_with_params(block.clone(), params) .new_circuit_input_builder(); + if is_taiko { + builder.block.protocol_instance = Some(ProtocolInstance::default()); + } builder .handle_block(&block.eth_block, &block.geth_traces) .unwrap(); diff --git a/zkevm-circuits/src/tx_circuit.rs b/zkevm-circuits/src/tx_circuit.rs index fa90e9108a..0c35dd49f6 100644 --- a/zkevm-circuits/src/tx_circuit.rs +++ b/zkevm-circuits/src/tx_circuit.rs @@ -28,12 +28,12 @@ use log::error; use sign_verify::{AssignedSignatureVerify, SignVerifyChip, SignVerifyConfig}; use std::marker::PhantomData; -/// Number of static fields per tx: [nonce, gas, gas_price, +/// Number of static fields per tx: [nonce, gas, gas_price, gas_tip_cap, gas_fee_cap, /// caller_address, callee_address, is_create, value, call_data_length, /// call_data_gas_cost, tx_sign_hash, r, s, v]. /// Note that call data bytes are layed out in the TxTable after all the static /// fields arranged by txs. -pub(crate) const TX_LEN: usize = 13; +pub(crate) const TX_LEN: usize = 15; /// Config for TxCircuit #[derive(Clone, Debug)] @@ -213,6 +213,18 @@ impl TxCircuit { .evm_word() .map(|challenge| rlc(tx.gas_price.to_le_bytes(), challenge)), ), + ( + TxFieldTag::GasTipCap, + challenges + .evm_word() + .map(|challenge| rlc(tx.gas_tip_cap.to_le_bytes(), challenge)), + ), + ( + TxFieldTag::GasFeeCap, + challenges + .evm_word() + .map(|challenge| rlc(tx.gas_fee_cap.to_le_bytes(), challenge)), + ), ( TxFieldTag::CallerAddress, Value::known(tx.from.to_scalar().expect("tx.from too big")), diff --git a/zkevm-circuits/src/witness.rs b/zkevm-circuits/src/witness.rs index 5874e6bad2..850979549f 100644 --- a/zkevm-circuits/src/witness.rs +++ b/zkevm-circuits/src/witness.rs @@ -3,7 +3,7 @@ //! used to generate witnesses for circuits. mod block; -pub use block::{block_convert, Block, BlockContext}; +pub use block::{block_convert, protocol_instance_table_assignments, Block, BlockContext}; mod bytecode; pub use bytecode::Bytecode; mod mpt; @@ -14,5 +14,3 @@ pub use rw::{Rw, RwMap, RwRow}; mod tx; pub use bus_mapping::circuit_input_builder::Call; pub use tx::Transaction; -mod protocol_instance; -pub use protocol_instance::{left_shift, MetaHash, ProtocolInstance}; diff --git a/zkevm-circuits/src/witness/block.rs b/zkevm-circuits/src/witness/block.rs index 73c4e99c57..bee18e10a3 100644 --- a/zkevm-circuits/src/witness/block.rs +++ b/zkevm-circuits/src/witness/block.rs @@ -3,17 +3,19 @@ use std::collections::HashMap; use crate::{ evm_circuit::{detect_fixed_table_tags, util::rlc, EvmCircuit}, exp_circuit::param::OFFSET_INCREMENT, - table::BlockContextFieldTag, - util::{log2_ceil, SubCircuit}, + table::{BlockContextFieldTag, PiFieldTag}, + util::{log2_ceil, rlc_be_bytes, SubCircuit}, }; use bus_mapping::{ - circuit_input_builder::{self, CircuitsParams, CopyEvent, ExpEvent}, + circuit_input_builder::{ + self, CircuitsParams, CopyEvent, ExpEvent, ProtocolInstance, ANCHOR_TX_METHOD_SIGNATURE, + }, Error, }; -use eth_types::{Address, Field, ToLittleEndian, ToScalar, ToWord, Word}; +use eth_types::{Address, Field, ToBigEndian, ToLittleEndian, ToScalar, ToWord, Word, H256}; use halo2_proofs::circuit::Value; -use super::{tx::tx_convert, Bytecode, ExecStep, ProtocolInstance, Rw, RwMap, Transaction}; +use super::{tx::tx_convert, Bytecode, ExecStep, Rw, RwMap, Transaction}; // TODO: Remove fields that are duplicated in`eth_block` /// Block is the struct used by all circuits, which contains all the needed @@ -52,7 +54,55 @@ pub struct Block { /// Original Block from geth pub eth_block: eth_types::Block, /// Protocol Instance - pub protocol_instance: ProtocolInstance, + pub protocol_instance: Option, +} + +/// Assignments for pi table +pub fn protocol_instance_table_assignments( + protocol_instance: &ProtocolInstance, + randomness: Value, +) -> [[Value; 2]; 6] { + [ + [ + Value::known(F::from(PiFieldTag::Null as u64)), + Value::known(F::ZERO), + ], + [ + Value::known(F::from(PiFieldTag::MethodSign as u64)), + Value::known(F::from(ANCHOR_TX_METHOD_SIGNATURE as u64)), + ], + [ + Value::known(F::from(PiFieldTag::L1Hash as u64)), + rlc_be_bytes( + &protocol_instance.meta_hash.l1_hash.to_fixed_bytes(), + randomness, + ), + ], + [ + Value::known(F::from(PiFieldTag::L1SignalRoot as u64)), + rlc_be_bytes(&protocol_instance.signal_root.to_fixed_bytes(), randomness), + ], + [ + Value::known(F::from(PiFieldTag::L1Height as u64)), + rlc_be_bytes( + &protocol_instance + .meta_hash + .l1_height + .to_word() + .to_be_bytes(), + randomness, + ), + ], + [ + Value::known(F::from(PiFieldTag::ParentGasUsed as u64)), + rlc_be_bytes( + &(protocol_instance.parent_gas_used as u64) + .to_word() + .to_be_bytes(), + randomness, + ), + ], + ] } impl Block { @@ -61,6 +111,11 @@ impl Block { self.rws[step.rw_index(index)] } + /// Set protocol instance means in taiko context + pub fn is_taiko(&self) -> bool { + self.protocol_instance.is_some() + } + /// Obtains the expected Circuit degree needed in order to be able to test /// the EvmCircuit with this block without needing to configure the /// `ConstraintSystem`. @@ -122,14 +177,18 @@ impl Block { pub struct BlockContext { /// The address of the miner for the block pub coinbase: Address, + /// The address of the treasury for the base fee + pub treasury: Option
, /// The gas limit of the block pub gas_limit: u64, /// The number of the block pub number: Word, /// The timestamp of the block pub timestamp: Word, - /// The difficulty of the blcok - pub difficulty: Word, + /// The mix hash of the block + // after eip-4399, the difficulty is always zero, we need to use the mix hash instead of + // difficulty. + pub mix_hash: H256, /// The base fee, the minimum amount of gas fee for a transaction pub base_fee: Word, /// The hash of previous blocks @@ -150,6 +209,11 @@ impl BlockContext { Value::known(F::ZERO), Value::known(self.coinbase.to_scalar().unwrap()), ], + [ + Value::known(F::from(BlockContextFieldTag::Treasury as u64)), + Value::known(F::ZERO), + Value::known(self.treasury.unwrap_or_default().to_scalar().unwrap()), + ], [ Value::known(F::from(BlockContextFieldTag::Timestamp as u64)), Value::known(F::ZERO), @@ -163,8 +227,7 @@ impl BlockContext { [ Value::known(F::from(BlockContextFieldTag::Difficulty as u64)), Value::known(F::ZERO), - randomness - .map(|randomness| rlc::value(&self.difficulty.to_le_bytes(), randomness)), + rlc_be_bytes(&self.mix_hash.to_fixed_bytes(), randomness), ], [ Value::known(F::from(BlockContextFieldTag::GasLimit as u64)), @@ -214,10 +277,14 @@ impl From<&circuit_input_builder::Block> for BlockContext { fn from(block: &circuit_input_builder::Block) -> Self { Self { coinbase: block.coinbase, + treasury: block + .protocol_instance + .as_ref() + .map(|pi| pi.meta_hash.treasury), gas_limit: block.gas_limit, number: block.number, timestamp: block.timestamp, - difficulty: block.difficulty, + mix_hash: block.mix_hash, base_fee: block.base_fee, history_hashes: block.history_hashes.clone(), chain_id: block.chain_id, @@ -269,6 +336,6 @@ pub fn block_convert( // keccak_inputs: circuit_input_builder::keccak_inputs(block, code_db)?, keccak_inputs: block.sha3_inputs.clone(), eth_block: block.eth_block.clone(), - protocol_instance: ProtocolInstance::default(), + protocol_instance: block.protocol_instance.clone(), }) } diff --git a/zkevm-circuits/src/witness/tx.rs b/zkevm-circuits/src/witness/tx.rs index 80780aa94b..729b78758e 100644 --- a/zkevm-circuits/src/witness/tx.rs +++ b/zkevm-circuits/src/witness/tx.rs @@ -23,6 +23,10 @@ pub struct Transaction { pub gas: u64, /// The gas price pub gas_price: Word, + /// The gas tip cap + pub gas_tip_cap: Word, + /// The gas fee cap + pub gas_fee_cap: Word, /// The caller address pub caller_address: Address, /// The callee address @@ -52,6 +56,11 @@ pub struct Transaction { } impl Transaction { + /// Return true if it is the first transaction. + pub fn is_first_tx(&self) -> bool { + self.id == 1 + } + /// Assignments for tx table, split into tx_data (all fields except /// calldata) and tx_calldata pub fn table_assignments( @@ -79,6 +88,22 @@ impl Transaction { .evm_word() .map(|challenge| rlc::value(&self.gas_price.to_le_bytes(), challenge)), ], + [ + Value::known(F::from(self.id as u64)), + Value::known(F::from(TxContextFieldTag::GasTipCap as u64)), + Value::known(F::ZERO), + challenges + .evm_word() + .map(|challenge| rlc::value(&self.gas_tip_cap.to_le_bytes(), challenge)), + ], + [ + Value::known(F::from(self.id as u64)), + Value::known(F::from(TxContextFieldTag::GasFeeCap as u64)), + Value::known(F::ZERO), + challenges + .evm_word() + .map(|challenge| rlc::value(&self.gas_fee_cap.to_le_bytes(), challenge)), + ], [ Value::known(F::from(self.id as u64)), Value::known(F::from(TxContextFieldTag::CallerAddress as u64)), @@ -176,6 +201,8 @@ pub(super) fn tx_convert( nonce: tx.tx.nonce.as_u64(), gas: tx.gas(), gas_price: tx.tx.gas_price, + gas_tip_cap: tx.tx.gas_tip_cap, + gas_fee_cap: tx.tx.gas_fee_cap, caller_address: tx.tx.from, callee_address: tx.tx.to_or_contract_addr(), is_create: tx.is_create(), diff --git a/zkevm-circuits/tests/prover_error.rs b/zkevm-circuits/tests/prover_error.rs index ef70f98246..6a0ff397aa 100644 --- a/zkevm-circuits/tests/prover_error.rs +++ b/zkevm-circuits/tests/prover_error.rs @@ -83,6 +83,7 @@ fn prover_error() { accounts.clone(), Some(history_hashes.clone()), LoggerConfig::default(), + false, ) .expect("gen_geth_traces"); let geth_data = GethData {