From 0d391dd1d78baeb48bc502cd7e2ad29add2ad54d Mon Sep 17 00:00:00 2001 From: z2trillion Date: Thu, 14 Jul 2022 10:19:08 -0400 Subject: [PATCH 1/4] wip --- .../circuit_input_builder/input_state_ref.rs | 25 +++++++++++++++++++ bus-mapping/src/evm/opcodes.rs | 9 ++++--- .../src/evm_circuit/execution/end_tx.rs | 4 +++ .../evm_circuit/util/constraint_builder.rs | 13 ++-------- zkevm-circuits/src/state_circuit.rs | 9 +++---- 5 files changed, 39 insertions(+), 21 deletions(-) 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 49d77d47e7..8c3a273f80 100644 --- a/bus-mapping/src/circuit_input_builder/input_state_ref.rs +++ b/bus-mapping/src/circuit_input_builder/input_state_ref.rs @@ -351,6 +351,31 @@ impl<'a> CircuitInputStateRef<'a> { Ok(()) } + /// Push a write type [`TxReceiptOp`] into the + /// [`OperationContainer`](crate::operation::OperationContainer) with the + /// next [`RWCounter`](crate::operation::RWCounter), and then + /// adds a reference to the stored operation ([`OperationRef`]) inside + /// the bus-mapping instance of the current [`ExecStep`]. Then increase + /// the `block_ctx` [`RWCounter`](crate::operation::RWCounter) by one. + pub fn tx_receipt_write( + &mut self, + step: &mut ExecStep, + tx_id: usize, + field: TxReceiptField, + value: u64, + ) -> Result<(), Error> { + self.push_op( + step, + RW::WRITE, + TxReceiptOp { + tx_id, + field, + value, + }, + ); + Ok(()) + } + /// Push a write type [`TxAccessListAccountOp`] into the /// [`OperationContainer`](crate::operation::OperationContainer) with the /// next [`RWCounter`](crate::operation::RWCounter), and then diff --git a/bus-mapping/src/evm/opcodes.rs b/bus-mapping/src/evm/opcodes.rs index 1c4b4caf96..fa9932af15 100644 --- a/bus-mapping/src/evm/opcodes.rs +++ b/bus-mapping/src/evm/opcodes.rs @@ -374,6 +374,7 @@ pub fn gen_begin_tx_ops(state: &mut CircuitInputStateRef) -> Result, ) -> Result { let mut exec_step = state.new_end_tx_step(); @@ -438,7 +439,7 @@ pub fn gen_end_tx_ops( )?; // handle tx receipt tag - state.tx_receipt_read( + state.tx_receipt_write( &mut exec_step, state.tx_ctx.id(), TxReceiptField::PostStateOrStatus, @@ -446,7 +447,7 @@ pub fn gen_end_tx_ops( )?; let log_id = exec_step.log_id; - state.tx_receipt_read( + state.tx_receipt_write( &mut exec_step, state.tx_ctx.id(), TxReceiptField::LogLength, @@ -458,7 +459,7 @@ pub fn gen_end_tx_ops( if state.tx_ctx.id() > 1 { current_cumulative_gas_used = *cumulative_gas_used.get(&(state.tx_ctx.id() - 1)).unwrap(); // query pre tx cumulative gas - state.tx_receipt_read( + state.tx_receipt_write( &mut exec_step, state.tx_ctx.id() - 1, TxReceiptField::CumulativeGasUsed, @@ -466,7 +467,7 @@ pub fn gen_end_tx_ops( )?; } - state.tx_receipt_read( + state.tx_receipt_write( &mut exec_step, state.tx_ctx.id(), TxReceiptField::CumulativeGasUsed, diff --git a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs index 3a37717e7c..65812c3e68 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs @@ -104,11 +104,13 @@ impl ExecutionGadget for EndTxGadget { // constrain tx receipt fields cb.tx_receipt_lookup( + 1.expr(), tx_id.expr(), TxReceiptFieldTag::PostStateOrStatus, is_persistent.expr(), ); cb.tx_receipt_lookup( + 1.expr(), tx_id.expr(), TxReceiptFieldTag::LogLength, cb.curr.state.log_id.expr(), @@ -126,6 +128,7 @@ impl ExecutionGadget for EndTxGadget { cb.condition(1.expr() - is_first_tx.expr(), |cb| { cb.tx_receipt_lookup( + 1.expr(), tx_id.expr() - 1.expr(), TxReceiptFieldTag::CumulativeGasUsed, current_cumulative_gas_used.expr(), @@ -133,6 +136,7 @@ impl ExecutionGadget for EndTxGadget { }); cb.tx_receipt_lookup( + 1.expr(), tx_id.expr(), TxReceiptFieldTag::CumulativeGasUsed, gas_used + current_cumulative_gas_used.expr(), diff --git a/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs b/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs index a19235c0ca..19801429b9 100644 --- a/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs +++ b/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs @@ -1041,25 +1041,16 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { // Tx Receipt - pub(crate) fn tx_receipt( - &mut self, - tx_id: Expression, - field_tag: TxReceiptFieldTag, - ) -> Cell { - let cell = self.query_cell(); - self.tx_receipt_lookup(tx_id, field_tag, cell.expr()); - cell - } - pub(crate) fn tx_receipt_lookup( &mut self, + is_write: Expression, tx_id: Expression, tag: TxReceiptFieldTag, value: Expression, ) { self.rw_lookup( "tx receipt lookup", - 0.expr(), + is_write, RwTableTag::TxReceipt, [ tx_id, diff --git a/zkevm-circuits/src/state_circuit.rs b/zkevm-circuits/src/state_circuit.rs index 8ac3043a7b..85e6c72822 100644 --- a/zkevm-circuits/src/state_circuit.rs +++ b/zkevm-circuits/src/state_circuit.rs @@ -241,12 +241,9 @@ impl Circuit for StateCircuit { // TODO: Get initial_values from MPT updates instead. if is_first_access { - // TODO: Set initial values for Rw::CallContext and Rw::TxReceipt to be - // 0 instead of special casing them. - initial_value = if matches!( - row.tag(), - RwTableTag::CallContext | RwTableTag::TxReceipt - ) { + // TODO: Set initial values for Rw::CallContext to be 0 instead of + // special casing them. + initial_value = if matches!(row.tag(), RwTableTag::CallContext) { row.value_assignment(self.randomness) } else { row.value_prev_assignment(self.randomness) From 8e5e7183f359f10c63ae7437eaa868ee5b4107e9 Mon Sep 17 00:00:00 2001 From: z2trillion Date: Thu, 14 Jul 2022 10:25:09 -0400 Subject: [PATCH 2/4] Don't write for 2nd access --- bus-mapping/src/evm/opcodes.rs | 2 +- zkevm-circuits/src/evm_circuit/execution/end_tx.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bus-mapping/src/evm/opcodes.rs b/bus-mapping/src/evm/opcodes.rs index fa9932af15..0f3bbc7f89 100644 --- a/bus-mapping/src/evm/opcodes.rs +++ b/bus-mapping/src/evm/opcodes.rs @@ -459,7 +459,7 @@ pub fn gen_end_tx_ops( if state.tx_ctx.id() > 1 { current_cumulative_gas_used = *cumulative_gas_used.get(&(state.tx_ctx.id() - 1)).unwrap(); // query pre tx cumulative gas - state.tx_receipt_write( + state.tx_receipt_read( &mut exec_step, state.tx_ctx.id() - 1, TxReceiptField::CumulativeGasUsed, diff --git a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs index 65812c3e68..7dab0555db 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs @@ -128,7 +128,7 @@ impl ExecutionGadget for EndTxGadget { cb.condition(1.expr() - is_first_tx.expr(), |cb| { cb.tx_receipt_lookup( - 1.expr(), + 0.expr(), tx_id.expr() - 1.expr(), TxReceiptFieldTag::CumulativeGasUsed, current_cumulative_gas_used.expr(), From 413aef4077994c4cce59014f90fe3ff0de565d2e Mon Sep 17 00:00:00 2001 From: z2trillion Date: Thu, 14 Jul 2022 10:43:35 -0400 Subject: [PATCH 3/4] Move cumulative gas used into block context --- bus-mapping/src/circuit_input_builder.rs | 14 ++------------ bus-mapping/src/circuit_input_builder/block.rs | 3 +++ bus-mapping/src/evm/opcodes.rs | 17 ++++------------- 3 files changed, 9 insertions(+), 25 deletions(-) diff --git a/bus-mapping/src/circuit_input_builder.rs b/bus-mapping/src/circuit_input_builder.rs index 41a9576553..7424f07af9 100644 --- a/bus-mapping/src/circuit_input_builder.rs +++ b/bus-mapping/src/circuit_input_builder.rs @@ -138,15 +138,9 @@ impl<'a> CircuitInputBuilder { geth_traces: &[eth_types::GethExecTrace], ) -> Result<(), Error> { // accumulates gas across all txs in the block - let mut cumulative_gas_used = HashMap::new(); for (tx_index, tx) in eth_block.transactions.iter().enumerate() { let geth_trace = &geth_traces[tx_index]; - self.handle_tx( - tx, - geth_trace, - tx_index + 1 == eth_block.transactions.len(), - &mut cumulative_gas_used, - )?; + self.handle_tx(tx, geth_trace, tx_index + 1 == eth_block.transactions.len())?; } self.set_value_ops_call_context_rwc_eor(); Ok(()) @@ -162,7 +156,6 @@ impl<'a> CircuitInputBuilder { eth_tx: ð_types::Transaction, geth_trace: &GethExecTrace, is_last_tx: bool, - cumulative_gas_used: &mut HashMap, ) -> Result<(), Error> { let mut tx = self.new_tx(eth_tx, !geth_trace.failed)?; let mut tx_ctx = TransactionContext::new(eth_tx, geth_trace, is_last_tx)?; @@ -189,10 +182,7 @@ impl<'a> CircuitInputBuilder { // - execution_state: EndTx // - op: None // Generate EndTx step - let end_tx_step = gen_end_tx_ops( - &mut self.state_ref(&mut tx, &mut tx_ctx), - cumulative_gas_used, - )?; + let end_tx_step = gen_end_tx_ops(&mut self.state_ref(&mut tx, &mut tx_ctx))?; tx.steps_mut().push(end_tx_step); self.sdb.commit_tx(); diff --git a/bus-mapping/src/circuit_input_builder/block.rs b/bus-mapping/src/circuit_input_builder/block.rs index d8f2d007f5..e1c0186a3c 100644 --- a/bus-mapping/src/circuit_input_builder/block.rs +++ b/bus-mapping/src/circuit_input_builder/block.rs @@ -18,6 +18,8 @@ pub struct BlockContext { /// in Block.txs and call_index is the index used in Transaction. /// calls). pub(crate) call_map: HashMap, + /// Total gas used by previous transactions in this block. + pub(crate) cumulative_gas_used: u64, } impl Default for BlockContext { @@ -32,6 +34,7 @@ impl BlockContext { Self { rwc: RWCounter::new(), call_map: HashMap::new(), + cumulative_gas_used: 0, } } } diff --git a/bus-mapping/src/evm/opcodes.rs b/bus-mapping/src/evm/opcodes.rs index 0f3bbc7f89..5bca084711 100644 --- a/bus-mapping/src/evm/opcodes.rs +++ b/bus-mapping/src/evm/opcodes.rs @@ -15,7 +15,6 @@ use eth_types::{ }; use keccak256::EMPTY_HASH; use log::warn; -use std::collections::HashMap; mod call; mod calldatacopy; @@ -372,11 +371,7 @@ pub fn gen_begin_tx_ops(state: &mut CircuitInputStateRef) -> Result, -) -> Result { +pub fn gen_end_tx_ops(state: &mut CircuitInputStateRef) -> Result { let mut exec_step = state.new_end_tx_step(); let call = state.tx.calls()[0].clone(); @@ -454,28 +449,24 @@ pub fn gen_end_tx_ops( log_id as u64, )?; - let gas_used = state.tx.gas - exec_step.gas_left.0; - let mut current_cumulative_gas_used: u64 = 0; if state.tx_ctx.id() > 1 { - current_cumulative_gas_used = *cumulative_gas_used.get(&(state.tx_ctx.id() - 1)).unwrap(); // query pre tx cumulative gas state.tx_receipt_read( &mut exec_step, state.tx_ctx.id() - 1, TxReceiptField::CumulativeGasUsed, - current_cumulative_gas_used, + state.block_ctx.cumulative_gas_used, )?; } + state.block_ctx.cumulative_gas_used += state.tx.gas - exec_step.gas_left.0; state.tx_receipt_write( &mut exec_step, state.tx_ctx.id(), TxReceiptField::CumulativeGasUsed, - current_cumulative_gas_used + gas_used, + state.block_ctx.cumulative_gas_used, )?; - cumulative_gas_used.insert(state.tx_ctx.id(), current_cumulative_gas_used + gas_used); - if !state.tx_ctx.is_last_tx() { state.call_context_read( &mut exec_step, From acb73e242f7be4ef64f4f67ef3211cf29275916e Mon Sep 17 00:00:00 2001 From: z2trillion Date: Thu, 14 Jul 2022 10:47:15 -0400 Subject: [PATCH 4/4] fix comment --- zkevm-circuits/src/state_circuit.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zkevm-circuits/src/state_circuit.rs b/zkevm-circuits/src/state_circuit.rs index 85e6c72822..16cd019b44 100644 --- a/zkevm-circuits/src/state_circuit.rs +++ b/zkevm-circuits/src/state_circuit.rs @@ -242,7 +242,7 @@ impl Circuit for StateCircuit { // TODO: Get initial_values from MPT updates instead. if is_first_access { // TODO: Set initial values for Rw::CallContext to be 0 instead of - // special casing them. + // special casing it. initial_value = if matches!(row.tag(), RwTableTag::CallContext) { row.value_assignment(self.randomness) } else {