Skip to content

Commit

Permalink
feat(1559): constrain tx gas price == effective gas price (#1152)
Browse files Browse the repository at this point in the history
* add tx gas price check

* constrain effective_gas_price

* increase width & bytes for lookup as more were required

* clippy fix

* increase STEP_WIDTH again for scroll feature

* set tx gas price in test

* enable more 1559 tests

* correct effective gas

* restore two tests

* remove used comment

* add missing constraint

* remove gas price as it's set in mock block

* add comment & rename

* rename

---------

Co-authored-by: Zhang Zhuo <[email protected]>
  • Loading branch information
DreamWuGit and lispc authored Apr 22, 2024
1 parent cfcb073 commit b1bb7c7
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
1 change: 1 addition & 0 deletions zkevm-circuits/src/evm_circuit/execution/begin_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
tx_id.expr(),
tx_type.expr(),
tx_gas.expr(),
&tx_gas_price,
tx_l1_fee.tx_l1_fee_word(),
&tx_value,
transfer_with_gas_fee.sender_balance_prev(),
Expand Down
4 changes: 2 additions & 2 deletions zkevm-circuits/src/evm_circuit/param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use halo2_proofs::{
use std::{collections::HashMap, sync::LazyLock};

// Step dimension
pub(crate) const STEP_WIDTH: usize = 144;
pub(crate) const STEP_WIDTH: usize = 153;
/// Step height
pub const MAX_STEP_HEIGHT: usize = 21;
/// The height of the state of a step, used by gates that connect two
Expand All @@ -27,7 +27,7 @@ pub(crate) const N_COPY_COLUMNS: usize = 2;
// Number of copy columns for phase2
pub(crate) const N_PHASE2_COPY_COLUMNS: usize = 1;

pub(crate) const N_BYTE_LOOKUPS: usize = 39;
pub(crate) const N_BYTE_LOOKUPS: usize = 48;

/// Amount of lookup columns in the EVM circuit dedicated to lookups.
pub(crate) const EVM_LOOKUP_COLS: usize = FIXED_TABLE_LOOKUPS
Expand Down
60 changes: 60 additions & 0 deletions zkevm-circuits/src/evm_circuit/util/common_gadget/tx_eip1559.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::{
table::{BlockContextFieldTag, TxFieldTag},
};
use eth_types::{geth_types::TxType, Field, ToLittleEndian, U256};
use gadgets::util::select;
use halo2_proofs::plonk::{Error, Expression};

/// Transaction EIP-1559 gadget to check sender balance before transfer
Expand All @@ -27,6 +28,14 @@ pub(crate) struct TxEip1559Gadget<F> {
gas_fee_cap: Word<F>,
// MaxPriorityFeePerGas
gas_tip_cap: Word<F>,
// condition for min(
// gas_tip_cap, gas_fee_cap - base_fee_per_gas)
lt_gas_tip_cap_vs_gas_fee_cap_sub_base_fee: LtWordGadget<F>,
// gas_fee_cap - base_fee_per_gas
gas_sub_base_fee: AddWordsGadget<F, 2, true>,
// check tx_gas_price = effective_gas_price = priority_fee_per_gas +
// block.base_fee_per_gas
effective_gas_price_check: AddWordsGadget<F, 2, true>,
mul_gas_fee_cap_by_gas: MulWordByU64Gadget<F>,
balance_check: AddWordsGadget<F, 3, true>,
// Error condition
Expand All @@ -43,11 +52,14 @@ pub(crate) struct TxEip1559Gadget<F> {
}

impl<F: Field> TxEip1559Gadget<F> {
#[allow(clippy::too_many_arguments)]
pub(crate) fn construct(
cb: &mut EVMConstraintBuilder<F>,
tx_id: Expression<F>,
tx_type: Expression<F>,
tx_gas: Expression<F>,
// tx_gas_price is looked up from TxTable in begin_tx gadget.
tx_gas_price: &Word<F>,
tx_l1_fee: &Word<F>,
value: &Word<F>,
sender_balance: &Word<F>,
Expand All @@ -65,6 +77,9 @@ impl<F: Field> TxEip1559Gadget<F> {
gas_fee_cap_lt_gas_tip_cap,
base_fee,
gas_fee_cap_lt_base_fee,
lt_gas_tip_gas_fee_sub_base_fee,
gas_sub_base_fee,
effective_gas_price_check,
) = cb.condition(is_eip1559_tx.expr(), |cb| {
let mul_gas_fee_cap_by_gas =
MulWordByU64Gadget::construct(cb, gas_fee_cap.clone(), tx_gas);
Expand All @@ -90,6 +105,22 @@ impl<F: Field> TxEip1559Gadget<F> {
let gas_fee_cap_lt_base_fee =
LtWordGadget::construct(cb, &gas_fee_cap, &base_fee);

// calculating min(
// gas_tip_cap
// gas_fee_cap - base_fee_per_gas,
// );
let diff_gas_base_fee = cb.query_word_rlc();
let gas_sub_base_fee = AddWordsGadget::construct(cb, [base_fee.clone(), diff_gas_base_fee.clone()], gas_fee_cap.clone());
let lt_gas_tip_gas_fee_sub_base_fee = LtWordGadget::construct(cb, &gas_tip_cap, &diff_gas_base_fee);
// let effective_gas_price = priority_fee_per_gas + base_fee_per_gas;
let priority_fee_per_gas = cb.query_word_rlc();
cb.require_equal("constrain priority_fee_per_gas = min(gas_tip_cap, gas_fee_cap - base_fee_per_gas)", priority_fee_per_gas.expr(), select::expr(
lt_gas_tip_gas_fee_sub_base_fee.expr(),
gas_tip_cap.expr(),
diff_gas_base_fee.expr()));
// constrain tx_gas_price = effective_gas_price within below `AddWordsGadget`.
let effective_gas_price_check = AddWordsGadget::construct(cb, [base_fee.clone(), priority_fee_per_gas], tx_gas_price.clone());

cb.require_zero(
"Sender balance must be sufficient, and gas_fee_cap >= gas_tip_cap, and gas_fee_cap >= base_fee",
sum::expr([
Expand All @@ -106,13 +137,19 @@ impl<F: Field> TxEip1559Gadget<F> {
gas_fee_cap_lt_gas_tip_cap,
base_fee,
gas_fee_cap_lt_base_fee,
lt_gas_tip_gas_fee_sub_base_fee,
gas_sub_base_fee,
effective_gas_price_check,
)
});

Self {
is_eip1559_tx,
gas_fee_cap,
gas_tip_cap,
lt_gas_tip_cap_vs_gas_fee_cap_sub_base_fee: lt_gas_tip_gas_fee_sub_base_fee,
gas_sub_base_fee,
effective_gas_price_check,
mul_gas_fee_cap_by_gas,
balance_check,
is_insufficient_balance,
Expand Down Expand Up @@ -144,6 +181,29 @@ impl<F: Field> TxEip1559Gadget<F> {
offset,
Some(tx.max_priority_fee_per_gas.to_le_bytes()),
)?;

let diff_gas_base_fee = tx.max_fee_per_gas - base_fee;
let effective_gas_price = base_fee + tx.max_priority_fee_per_gas.min(diff_gas_base_fee);
self.gas_sub_base_fee.assign(
region,
offset,
[base_fee, diff_gas_base_fee],
tx.max_fee_per_gas,
)?;
self.lt_gas_tip_cap_vs_gas_fee_cap_sub_base_fee.assign(
region,
offset,
tx.max_priority_fee_per_gas,
diff_gas_base_fee,
)?;

self.effective_gas_price_check.assign(
region,
offset,
[base_fee, effective_gas_price],
tx.gas_price,
)?;

let mul_gas_fee_cap_by_gas = tx.max_fee_per_gas * tx.gas;
self.mul_gas_fee_cap_by_gas.assign(
region,
Expand Down

0 comments on commit b1bb7c7

Please sign in to comment.