Skip to content

Commit

Permalink
Add coinbase to access list in begin_tx for EIP-3651 of Shanghai.
Browse files Browse the repository at this point in the history
  • Loading branch information
silathdiir committed May 9, 2023
1 parent 9d6aa63 commit 8dd448e
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 12 deletions.
17 changes: 15 additions & 2 deletions bus-mapping/src/evm/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,8 +497,21 @@ pub fn gen_begin_tx_ops(
nonce_prev,
)?;

// Add caller and callee into access list
for address in [call.caller_address, call.address] {
// Add caller, callee and coinbase (only for Shanghai) to access list.
#[cfg(feature = "shanghai")]
let accessed_addresses = [
call.caller_address,
call.address,
state
.block
.headers
.get(&state.tx.block_num)
.unwrap()
.coinbase,
];
#[cfg(not(feature = "shanghai"))]
let accessed_addresses = [call.caller_address, call.address];
for address in accessed_addresses {
let is_warm_prev = !state.sdb.add_account_to_access_list(address);
state.tx_accesslist_account_write(
&mut exec_step,
Expand Down
84 changes: 74 additions & 10 deletions zkevm-circuits/src/evm_circuit/execution/begin_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,21 @@ use crate::{
},
witness::{Block, Call, ExecStep, Transaction},
},
table::{AccountFieldTag, CallContextFieldTag, TxFieldTag as TxContextFieldTag},
table::{
AccountFieldTag, BlockContextFieldTag, CallContextFieldTag, TxFieldTag as TxContextFieldTag,
},
};
use eth_types::{Address, Field, ToLittleEndian, ToScalar};
use ethers_core::utils::{get_contract_address, keccak256, rlp::RlpStream};
use gadgets::util::{expr_from_bytes, not, or, Expr};
use halo2_proofs::{circuit::Value, plonk::Error};

// For Shanghai, EIP-3651 (Warm COINBASE) adds 1 write op for coinbase.
#[cfg(feature = "shanghai")]
const SHANGHAI_RW_DELTA: u8 = 1;
#[cfg(not(feature = "shanghai"))]
const SHANGHAI_RW_DELTA: u8 = 0;

#[cfg(feature = "reject-eip2718")]
use gadgets::util::select;

Expand Down Expand Up @@ -59,6 +67,12 @@ pub(crate) struct BeginTxGadget<F> {
create: ContractCreateGadget<F, false>,
callee_not_exists: IsZeroGadget<F>,
is_caller_callee_equal: Cell<F>,
// EIP-3651 (Warm COINBASE) for Shanghai
coinbase: Cell<F>,
// Caller, callee and a list addresses are added to the access list before
// coinbase, and may be duplicate.
// <https://github.com/ethereum/go-ethereum/blob/604e215d1bb070dff98fb76aa965064c74e3633f/core/state/statedb.go#LL1119C9-L1119C9>
is_coinbase_warm: Cell<F>,
}

impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
Expand Down Expand Up @@ -200,6 +214,24 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
None,
); // rwc_delta += 1

// Query coinbase address for Shanghai.
let coinbase = cb.query_cell();
let is_coinbase_warm = cb.query_bool();
cb.block_lookup(
BlockContextFieldTag::Coinbase.expr(),
cb.curr.state.block_number.expr(),
coinbase.expr(),
);

#[cfg(feature = "shanghai")]
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 =
Expand Down Expand Up @@ -316,8 +348,9 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
// - Write CallContext IsPersistent
// - Write CallContext IsSuccess
// - Write Account (Caller) Nonce
// - Write TxAccessListAccount
// - Write TxAccessListAccount
// - Write TxAccessListAccount (Caller)
// - Write TxAccessListAccount (Callee)
// - Write TxAccessListAccount (Coinbase) only for Shanghai
// - a TransferWithGasFeeGadget
// - Write Account (Callee) Nonce (Reversible)
// - Write CallContext Depth
Expand All @@ -333,7 +366,9 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
// - Write CallContext IsRoot
// - Write CallContext IsCreate
// - Write CallContext CodeHash
rw_counter: Delta(21.expr() + transfer_with_gas_fee.rw_delta()),
rw_counter: Delta(
21.expr() + transfer_with_gas_fee.rw_delta() + SHANGHAI_RW_DELTA.expr(),
),
call_id: To(call_id.expr()),
is_root: To(true.expr()),
is_create: To(tx_is_create.expr()),
Expand Down Expand Up @@ -377,10 +412,12 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
// - Write Account (Caller) Nonce
// - Write TxAccessListAccount (Caller)
// - Write TxAccessListAccount (Callee)
// - Write TxAccessListAccount (Coinbase) only for Shanghai
// - a TransferWithGasFeeGadget
rw_counter: Delta(
7.expr()
+ transfer_with_gas_fee.rw_delta()
+ SHANGHAI_RW_DELTA.expr()
// TRICKY:
// Process the reversion only for Precompile in begin TX. Since no
// associated opcodes could process reversion afterwards
Expand Down Expand Up @@ -421,11 +458,14 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
// - Write CallContext IsPersistent
// - Write CallContext IsSuccess
// - Write Account Nonce
// - Write TxAccessListAccount
// - Write TxAccessListAccount
// - Write TxAccessListAccount (Caller)
// - Write TxAccessListAccount (Callee)
// - Write TxAccessListAccount (Coinbase) only for Shanghai
// - Read Account CodeHash
// - a TransferWithGasFeeGadget
rw_counter: Delta(8.expr() + transfer_with_gas_fee.rw_delta()),
rw_counter: Delta(
8.expr() + transfer_with_gas_fee.rw_delta() + SHANGHAI_RW_DELTA.expr(),
),
call_id: To(call_id.expr()),
..StepStateTransition::any()
});
Expand Down Expand Up @@ -468,8 +508,9 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
// - Write CallContext IsPersistent
// - Write CallContext IsSuccess
// - Write Account Nonce
// - Write TxAccessListAccount
// - Write TxAccessListAccount
// - Write TxAccessListAccount (Caller)
// - Write TxAccessListAccount (Callee)
// - Write TxAccessListAccount (Coinbase) only for Shanghai
// - Read Account CodeHash
// - a TransferWithGasFeeGadget
// - Write CallContext Depth
Expand All @@ -485,7 +526,9 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
// - Write CallContext IsRoot
// - Write CallContext IsCreate
// - Write CallContext CodeHash
rw_counter: Delta(21.expr() + transfer_with_gas_fee.rw_delta()),
rw_counter: Delta(
21.expr() + transfer_with_gas_fee.rw_delta() + SHANGHAI_RW_DELTA.expr(),
),
call_id: To(call_id.expr()),
is_root: To(true.expr()),
is_create: To(tx_is_create.expr()),
Expand Down Expand Up @@ -525,6 +568,8 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
create,
callee_not_exists,
is_caller_callee_equal,
coinbase,
is_coinbase_warm,
}
}

Expand All @@ -541,6 +586,12 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {

let mut rws = StepRws::new(block, step);
rws.offset_add(7);

#[cfg(feature = "shanghai")]
let is_coinbase_warm = rws.next().tx_access_list_value_pair().1;
#[cfg(not(feature = "shanghai"))]
let is_coinbase_warm = false;

let mut callee_code_hash = zero;
if !tx.is_create && !is_precompiled(&tx.callee_address.unwrap_or_default()) {
callee_code_hash = rws.next().account_codehash_pair().1;
Expand Down Expand Up @@ -700,6 +751,19 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
None,
)?;

self.coinbase.assign(
region,
offset,
Value::known(
block.context.ctxs[&tx.block_number]
.coinbase
.to_scalar()
.expect("unexpected Address -> Scalar conversion failure"),
),
)?;
self.is_coinbase_warm
.assign(region, offset, Value::known(F::from(is_coinbase_warm)))?;

Ok(())
}
}
Expand Down

0 comments on commit 8dd448e

Please sign in to comment.