Skip to content

Commit

Permalink
eip1559 gadget: constrain gas_fee_cap >= base_fee (#1120)
Browse files Browse the repository at this point in the history
* add gas_fee_cap_lt_base_fee

* fix fmt

* increase STEP_WIDTH &N_BYTE_LOOKUPS as more byte cells required

* revise comment

* increase STEP_WIDTH: scroll feature needs more cells

* add new constraint to doc
  • Loading branch information
DreamWuGit authored Feb 27, 2024
1 parent 44fd11f commit b39e7d8
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 10 deletions.
8 changes: 5 additions & 3 deletions docs/EIP2930_1559.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ this doc describles how to support EIP2930 & 1559 in copy circuit and evm circui
- `gas_tip_cap`: MaxPriorityFeePerGas in 1559.
- `mul_gas_fee_cap_by_gas`: Calculates total gas amount.
- `balance_check`: Calculates minimal caller's balance required = `mul_gas_fee_cap_by_gas` + `tx.value` + `tx_l1_fee`.
- is_insufficient_balance: check balance is sufficient compared to
- `is_insufficient_balance`: check balance is sufficient compared to
minimal balance required.
- gas_fee_cap_lt_gas_tip_cap: make sure gas_fee_cap not less than gas_tip_gap.
- `gas_fee_cap_lt_gas_tip_cap`: make sure gas_fee_cap not less than gas_tip_gap.
- `base_fee`: base fee from block context.
- `gas_fee_cap_lt_base_fee`: make sure gas_fee_cap not less than base fee.
- constraints:
- tx table lookups for [MaxFeePerGas, MaxPriorityFeePerGas]
- sender balance must be sufficient, means gas_fee_cap >= gas_tip_cap
- sender balance must be sufficient, as well as gas_fee_cap >= gas_tip_cap, gas_fee_cap >= base_fee.
- `begin_tx` : take use of `TxAccessListGadget` and `TxEip1559Gadget` to implement corresponding constraints.
9 changes: 8 additions & 1 deletion zkevm-circuits/src/evm_circuit/execution/begin_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,13 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
)?;

self.tx_access_list.assign(region, offset, tx)?;

// get base_fee from block context
let base_fee = block
.context
.ctxs
.get(&tx.block_number)
.expect("cound not find block with number = {tx.block_number}")
.base_fee;
self.tx_eip1559.assign(
region,
offset,
Expand All @@ -1233,6 +1239,7 @@ impl<F: Field> ExecutionGadget<F> for BeginTxGadget<F> {
.sender_balance_sub_fee_pair
.unwrap()
.1,
base_fee,
)
}
}
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 = 141;
pub(crate) const STEP_WIDTH: usize = 144;
/// 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 = 36;
pub(crate) const N_BYTE_LOOKUPS: usize = 39;

/// Amount of lookup columns in the EVM circuit dedicated to lookups.
pub(crate) const EVM_LOOKUP_COLS: usize = FIXED_TABLE_LOOKUPS
Expand Down
31 changes: 27 additions & 4 deletions zkevm-circuits/src/evm_circuit/util/common_gadget/tx_eip1559.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{
},
witness::Transaction,
},
table::TxFieldTag,
table::{BlockContextFieldTag, TxFieldTag},
};
use eth_types::{geth_types::TxType, Field, ToLittleEndian, U256};
use halo2_proofs::plonk::{Error, Expression};
Expand All @@ -30,11 +30,16 @@ pub(crate) struct TxEip1559Gadget<F> {
mul_gas_fee_cap_by_gas: MulWordByU64Gadget<F>,
balance_check: AddWordsGadget<F, 3, true>,
// Error condition
// <https://github.com/ethereum/go-ethereum/blob/master/core/state_transition.go#L255>
// <https://github.com/ethereum/go-ethereum/blob/master/core/state_transition.go#L241>
is_insufficient_balance: LtWordGadget<F>,
// Error condition
// <https://github.com/ethereum/go-ethereum/blob/master/core/state_transition.go#L310>
gas_fee_cap_lt_gas_tip_cap: LtWordGadget<F>,
// base fee from block context
base_fee: Word<F>,
// Error condition
// <https://github.com/ethereum/go-ethereum/blob/master/core/state_transition.go#L316>
gas_fee_cap_lt_base_fee: LtWordGadget<F>,
}

impl<F: Field> TxEip1559Gadget<F> {
Expand All @@ -58,6 +63,8 @@ impl<F: Field> TxEip1559Gadget<F> {
balance_check,
is_insufficient_balance,
gas_fee_cap_lt_gas_tip_cap,
base_fee,
gas_fee_cap_lt_base_fee,
) = 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 @@ -76,12 +83,19 @@ impl<F: Field> TxEip1559Gadget<F> {
let is_insufficient_balance = LtWordGadget::construct(cb, sender_balance, &min_balance);
let gas_fee_cap_lt_gas_tip_cap =
LtWordGadget::construct(cb, &gas_fee_cap, &gas_tip_cap);
// lookup base fee from block.
let base_fee = cb.query_word_rlc();
cb.block_lookup(BlockContextFieldTag::BaseFee.expr(), cb.curr.state.block_number.expr(), base_fee.expr());
// constrain GasFeeCap not less than BaseFee
let gas_fee_cap_lt_base_fee =
LtWordGadget::construct(cb, &gas_fee_cap, &base_fee);

cb.require_zero(
"Sender balance must be sufficient, and gas_fee_cap >= gas_tip_cap",
"Sender balance must be sufficient, and gas_fee_cap >= gas_tip_cap, and gas_fee_cap >= base_fee",
sum::expr([
is_insufficient_balance.expr(),
gas_fee_cap_lt_gas_tip_cap.expr(),
gas_fee_cap_lt_base_fee.expr(),
]),
);

Expand All @@ -90,6 +104,8 @@ impl<F: Field> TxEip1559Gadget<F> {
balance_check,
is_insufficient_balance,
gas_fee_cap_lt_gas_tip_cap,
base_fee,
gas_fee_cap_lt_base_fee,
)
});

Expand All @@ -101,6 +117,8 @@ impl<F: Field> TxEip1559Gadget<F> {
balance_check,
is_insufficient_balance,
gas_fee_cap_lt_gas_tip_cap,
base_fee,
gas_fee_cap_lt_base_fee,
}
}

Expand All @@ -111,6 +129,7 @@ impl<F: Field> TxEip1559Gadget<F> {
tx: &Transaction,
tx_l1_fee: U256,
sender_balance_prev: U256,
base_fee: U256,
) -> Result<(), Error> {
self.is_eip1559_tx.assign(
region,
Expand Down Expand Up @@ -142,12 +161,16 @@ impl<F: Field> TxEip1559Gadget<F> {
)?;
self.is_insufficient_balance
.assign(region, offset, sender_balance_prev, min_balance)?;
self.base_fee
.assign(region, offset, Some(base_fee.to_le_bytes()))?;
self.gas_fee_cap_lt_gas_tip_cap.assign(
region,
offset,
tx.max_fee_per_gas,
tx.max_priority_fee_per_gas,
)
)?;
self.gas_fee_cap_lt_base_fee
.assign(region, offset, tx.max_fee_per_gas, base_fee)
}
}

Expand Down

0 comments on commit b39e7d8

Please sign in to comment.