Skip to content

Commit

Permalink
fix: anchor without updating balance
Browse files Browse the repository at this point in the history
  • Loading branch information
johntaiko committed Aug 7, 2023
1 parent 5e9573c commit 4bc10f8
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 76 deletions.
12 changes: 10 additions & 2 deletions bus-mapping/src/circuit_input_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ impl<'a> CircuitInputBuilder {
&mut self,
eth_tx: &eth_types::Transaction,
is_success: bool,
is_anchor: bool,
) -> Result<Transaction, Error> {
let call_id = self.block_ctx.rwc.0;

Expand All @@ -169,7 +170,14 @@ 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_tx,
is_success,
is_anchor,
)
}

/// Iterate over all generated CallContext RwCounterEndOfReversion
Expand Down Expand Up @@ -286,7 +294,7 @@ impl<'a> CircuitInputBuilder {
is_anchor_tx: bool,
is_last_tx: bool,
) -> Result<(), Error> {
let mut tx = self.new_tx(eth_tx, !geth_trace.failed)?;
let mut tx = self.new_tx(eth_tx, !geth_trace.failed, is_anchor_tx)?;
let mut tx_ctx = TransactionContext::new(eth_tx, geth_trace, is_anchor_tx, is_last_tx)?;

// Generate BeginTx step
Expand Down
4 changes: 4 additions & 0 deletions bus-mapping/src/circuit_input_builder/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ pub struct Transaction {
pub tx: geth_types::Transaction,
/// Calls made in the transaction
pub(crate) calls: Vec<Call>,
/// Whether this transaction is an anchor transaction
pub is_anchor: bool,
/// Execution steps
steps: Vec<ExecStep>,
}
Expand All @@ -203,6 +205,7 @@ impl Transaction {
code_db: &mut CodeDB,
eth_tx: &eth_types::Transaction,
is_success: bool,
is_anchor: bool,
) -> Result<Self, Error> {
let (found, _) = sdb.get_account(&eth_tx.from);
if !found {
Expand Down Expand Up @@ -255,6 +258,7 @@ impl Transaction {
tx: eth_tx.into(),
calls: vec![call],
steps: Vec::new(),
is_anchor,
})
}

Expand Down
100 changes: 51 additions & 49 deletions bus-mapping/src/evm/opcodes/begin_end_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,58 +248,60 @@ fn gen_end_tx_steps(state: &mut CircuitInputStateRef) -> Result<ExecStep, Error>
},
);

let effective_refund = refund
.min((state.tx.gas() - exec_step.gas_left.0) / MAX_REFUND_QUOTIENT_OF_GAS_USED as u64);
let (found, caller_account) = state.sdb.get_account(&call.caller_address);
if !found {
return Err(Error::AccountNotFound(call.caller_address));
}
let caller_balance_prev = caller_account.balance;
let caller_balance =
caller_balance_prev + state.tx.tx.gas_price * (exec_step.gas_left.0 + effective_refund);
state.account_write(
&mut exec_step,
call.caller_address,
AccountField::Balance,
caller_balance,
caller_balance_prev,
)?;
if !state.tx.is_anchor {
let effective_refund = refund
.min((state.tx.gas() - exec_step.gas_left.0) / MAX_REFUND_QUOTIENT_OF_GAS_USED as u64);
let (found, caller_account) = state.sdb.get_account(&call.caller_address);
if !found {
return Err(Error::AccountNotFound(call.caller_address));
}
let caller_balance_prev = caller_account.balance;
let caller_balance =
caller_balance_prev + state.tx.tx.gas_price * (exec_step.gas_left.0 + effective_refund);
state.account_write(
&mut exec_step,
call.caller_address,
AccountField::Balance,
caller_balance,
caller_balance_prev,
)?;

let effective_tip = state.tx.tx.gas_price - state.block.base_fee;
let (found, coinbase_account) = state.sdb.get_account(&state.block.coinbase);
if !found {
return Err(Error::AccountNotFound(state.block.coinbase));
}
let coinbase_balance_prev = coinbase_account.balance;
let coinbase_balance =
coinbase_balance_prev + effective_tip * (state.tx.gas() - exec_step.gas_left.0);
state.account_write(
&mut exec_step,
state.block.coinbase,
AccountField::Balance,
coinbase_balance,
coinbase_balance_prev,
)?;
let effective_tip = state.tx.tx.gas_price - state.block.base_fee;
let (found, coinbase_account) = state.sdb.get_account(&state.block.coinbase);
if !found {
return Err(Error::AccountNotFound(state.block.coinbase));
}
let coinbase_balance_prev = coinbase_account.balance;
let coinbase_reward = effective_tip * (state.tx.gas() - exec_step.gas_left.0);
let coinbase_balance = coinbase_balance_prev + coinbase_reward;
state.account_write(
&mut exec_step,
state.block.coinbase,
AccountField::Balance,
coinbase_balance,
coinbase_balance_prev,
)?;

// add treasury account
let (found, treasury_account) = state
.sdb
.get_account(&state.block.protocol_instance.meta_hash.treasury);
if !found {
return Err(Error::AccountNotFound(
state.block.protocol_instance.meta_hash.treasury,
));
// add treasury account
let (found, treasury_account) = state
.sdb
.get_account(&state.block.protocol_instance.meta_hash.treasury);
if !found {
return Err(Error::AccountNotFound(
state.block.protocol_instance.meta_hash.treasury,
));
}
let treasury_balance_prev = treasury_account.balance;
let treasury_balance =
treasury_balance_prev + state.block.base_fee * (state.tx.gas() - exec_step.gas_left.0);
state.account_write(
&mut exec_step,
state.block.coinbase,
AccountField::Balance,
treasury_balance,
treasury_balance_prev,
)?;
}
let treasury_balance_prev = treasury_account.balance;
let treasury_balance =
treasury_balance_prev + state.block.base_fee * (state.tx.gas() - exec_step.gas_left.0);
state.account_write(
&mut exec_step,
state.block.coinbase,
AccountField::Balance,
treasury_balance,
treasury_balance_prev,
)?;
// handle tx receipt tag
state.tx_receipt_write(
&mut exec_step,
Expand Down
54 changes: 31 additions & 23 deletions zkevm-circuits/src/evm_circuit/execution/end_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,6 @@ impl<F: Field> ExecutionGadget<F> for EndTxGadget<F> {
) -> Result<(), Error> {
let gas_used = tx.gas - step.gas_left.0;
let (refund, _) = block.get_rws(step, 2).tx_refund_value_pair();
let [(caller_balance, caller_balance_prev), (coinbase_balance, coinbase_balance_prev), (treasury_balance, treasury_balance_prev)] =
[3, 4, 5].map(|index| block.get_rws(step, index).account_value_pair());

self.tx_id
.assign(region, offset, Value::known(F::from(tx.id as u64)))?;
Expand All @@ -269,6 +267,7 @@ impl<F: Field> ExecutionGadget<F> for EndTxGadget<F> {
F::from(max_refund as u64),
F::from(refund),
)?;

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(
Expand All @@ -287,13 +286,6 @@ impl<F: Field> ExecutionGadget<F> for EndTxGadget<F> {
.expect("unexpected Address -> Scalar conversion failure"),
),
)?;
self.gas_fee_refund.assign(
region,
offset,
caller_balance_prev,
vec![gas_fee_refund],
caller_balance,
)?;
let effective_tip = tx.gas_price - block.context.base_fee;
self.sub_gas_price_by_base_fee.assign(
region,
Expand All @@ -314,6 +306,7 @@ impl<F: Field> ExecutionGadget<F> for EndTxGadget<F> {
gas_used,
effective_tip * gas_used,
)?;

self.coinbase.assign(
region,
offset,
Expand All @@ -325,13 +318,6 @@ impl<F: Field> ExecutionGadget<F> for EndTxGadget<F> {
.expect("unexpected Address -> Scalar conversion failure"),
),
)?;
self.coinbase_reward.assign(
region,
offset,
coinbase_balance_prev,
vec![effective_tip * gas_used],
coinbase_balance,
)?;
self.treasury.assign(
region,
offset,
Expand All @@ -344,13 +330,35 @@ impl<F: Field> ExecutionGadget<F> for EndTxGadget<F> {
.expect("unexpected Address -> Scalar conversion failure"),
),
)?;
self.treasury_reward.assign(
region,
offset,
treasury_balance_prev,
vec![block.context.base_fee * gas_used],
treasury_balance,
)?;

if tx.id != 1 {
let [(caller_balance, caller_balance_prev), (coinbase_balance, coinbase_balance_prev), (treasury_balance, treasury_balance_prev)] =
[3, 4, 5].map(|index| block.get_rws(step, index).account_value_pair());
self.gas_fee_refund.assign(
region,
offset,
caller_balance_prev,
vec![gas_fee_refund],
caller_balance,
)?;

self.coinbase_reward.assign(
region,
offset,
coinbase_balance_prev,
vec![effective_tip * gas_used],
coinbase_balance,
)?;

self.treasury_reward.assign(
region,
offset,
treasury_balance_prev,
vec![block.context.base_fee * gas_used],
treasury_balance,
)?;
}

let current_cumulative_gas_used: u64 = if tx.id == 1 {
0
} else {
Expand Down
2 changes: 1 addition & 1 deletion zkevm-circuits/src/evm_circuit/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub const N_PHASE1_COLUMNS: usize =
// Number of copy columns
pub const N_COPY_COLUMNS: usize = 2;

pub const N_BYTE_LOOKUPS: usize = 24;
pub const N_BYTE_LOOKUPS: usize = 28;

/// Amount of lookup columns in the EVM circuit dedicated to lookups.
pub(crate) const EVM_LOOKUP_COLS: usize = FIXED_TABLE_LOOKUPS
Expand Down
5 changes: 4 additions & 1 deletion zkevm-circuits/src/taiko_test_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,10 @@ impl<const NACC: usize, const NTX: usize> CircuitTestBuilder<NACC, NTX> {
fn empty() -> Self {
CircuitTestBuilder {
test_ctx: None,
circuits_params: None,
circuits_params: Some(CircuitsParams {
max_txs: 2,
..Default::default()
}),
block: None,
evm_checks: Box::new(|prover, gate_rows, lookup_rows| {
prover.assert_satisfied_at_rows_par(
Expand Down

0 comments on commit 4bc10f8

Please sign in to comment.