diff --git a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs index 751c9d4cd3..0b8464ed21 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs @@ -173,9 +173,7 @@ impl ExecutionGadget for EndTxGadget { ); cb.require_step_state_transition(StepStateTransition { - rw_counter: Delta( - 11.expr() - is_first_tx.expr() + coinbase_code_hash_is_zero.expr(), - ), + rw_counter: Delta(10.expr() - is_first_tx.expr() + coinbase_reward.rw_delta()), ..StepStateTransition::any() }); }, @@ -185,9 +183,7 @@ impl ExecutionGadget for EndTxGadget { cb.next.execution_state_selector([ExecutionState::EndBlock]), |cb| { cb.require_step_state_transition(StepStateTransition { - rw_counter: Delta( - 10.expr() - is_first_tx.expr() + coinbase_code_hash_is_zero.expr(), - ), + rw_counter: Delta(9.expr() - is_first_tx.expr() + coinbase_reward.rw_delta()), // We propagate call_id so that EndBlock can get the last tx_id // in order to count processed txs. call_id: Same, @@ -230,16 +226,6 @@ impl ExecutionGadget for EndTxGadget { let (refund, _) = block.get_rws(step, 2).tx_refund_value_pair(); let (caller_balance, caller_balance_prev) = block.get_rws(step, 3).account_balance_pair(); let (coinbase_code_hash_prev, _) = block.get_rws(step, 4).account_codehash_pair(); - let (coinbase_balance, coinbase_balance_prev) = block - .get_rws( - step, - if coinbase_code_hash_prev.is_zero() { - 6 - } else { - 5 - }, - ) - .account_balance_pair(); self.tx_id .assign(region, offset, Value::known(F::from(tx.id)))?; @@ -273,6 +259,7 @@ impl ExecutionGadget for EndTxGadget { caller_balance, )?; let effective_tip = tx.gas_price - block.context.base_fee; + let coinbase_reward = effective_tip * gas_used; self.sub_gas_price_by_base_fee.assign( region, offset, @@ -284,7 +271,7 @@ impl ExecutionGadget for EndTxGadget { offset, effective_tip, gas_used, - effective_tip * gas_used, + coinbase_reward, )?; self.coinbase .assign_h160(region, offset, block.context.coinbase)?; @@ -292,12 +279,24 @@ impl ExecutionGadget for EndTxGadget { .assign_u256(region, offset, coinbase_code_hash_prev)?; self.coinbase_code_hash_is_zero .assign_u256(region, offset, coinbase_code_hash_prev)?; - self.coinbase_reward.assign( - region, - offset, - (coinbase_balance, coinbase_balance_prev), - effective_tip * gas_used, - )?; + if !coinbase_reward.is_zero() { + let coinbase_balance_pair = block + .get_rws( + step, + if coinbase_code_hash_prev.is_zero() { + 6 + } else { + 5 + }, + ) + .account_balance_pair(); + self.coinbase_reward.assign( + region, + offset, + coinbase_balance_pair, + effective_tip * gas_used, + )?; + } let current_cumulative_gas_used: u64 = if tx.id == 1 { 0 diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index d5052e5613..0b695b0f94 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -427,6 +427,16 @@ impl TransferToGadget { .assign_value(region, offset, Value::known(Word::from(value)))?; Ok(()) } + + pub(crate) fn rw_delta(&self) -> Expression { + // +1 Write Account (receiver) CodeHash (account creation via code_hash update) + or::expr([ + not::expr(self.value_is_zero.expr()) * not::expr(self.receiver_exists.expr()), + self.must_create.clone()] + ) + + // +1 Write Account (receiver) Balance + not::expr(self.value_is_zero.expr()) + } } // TODO: Merge with TransferGadget