Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion cmd/ethrex/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::{

use clap::{ArgAction, Parser as ClapParser, Subcommand as ClapSubcommand};
use ethrex_blockchain::{
BlockchainOptions, BlockchainType, L2Config,
BlockchainOptions, BlockchainType, DEFAULT_MIN_TIP_WEI, L2Config,
error::{ChainError, InvalidBlockError},
};
use ethrex_common::types::{Block, DEFAULT_BUILDER_GAS_CEIL, Genesis, validate_block_body};
Expand Down Expand Up @@ -183,6 +183,15 @@ pub struct Options {
env = "ETHREX_MEMPOOL_MAX_SIZE"
)]
pub mempool_max_size: usize,
#[arg(
help = "Minimum priority-fee cap (in wei) required for a transaction to be admitted into the mempool. Compared against the raw tip cap: `max_priority_fee_per_gas` for typed transactions, `gas_price` for legacy transactions (independent of current base fee, so admission stays stable as base fee oscillates). Set to 0 to disable the floor.",
long = "mempool.min-tip",
default_value_t = DEFAULT_MIN_TIP_WEI,
value_name = "MIN_TIP_WEI",
help_heading = "Node options",
env = "ETHREX_MEMPOOL_MIN_TIP"
)]
Comment on lines +186 to +193
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pub mempool_min_tip: u64,
#[arg(
long = "http.addr",
default_value = "127.0.0.1",
Expand Down Expand Up @@ -464,6 +473,7 @@ impl Default for Options {
dev: Default::default(),
force: false,
mempool_max_size: Default::default(),
mempool_min_tip: DEFAULT_MIN_TIP_WEI,
tx_broadcasting_time_interval: Default::default(),
target_peers: Default::default(),
lookup_interval: Default::default(),
Expand Down
1 change: 1 addition & 0 deletions cmd/ethrex/initializers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ pub async fn init_l1(
max_blobs_per_block: opts.max_blobs_per_block,
precompute_witnesses: opts.precompute_witnesses,
precompile_cache_enabled: !opts.no_precompile_cache,
min_tip_wei: opts.mempool_min_tip,
},
);

Expand Down
1 change: 1 addition & 0 deletions cmd/ethrex/l2/initializers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ pub async fn init_l2(
max_blobs_per_block: None, // L2 doesn't support blob transactions
precompute_witnesses: opts.node_opts.precompute_witnesses,
precompile_cache_enabled: true,
min_tip_wei: opts.node_opts.mempool_min_tip,
};

let blockchain = init_blockchain(store.clone(), blockchain_opts.clone());
Expand Down
36 changes: 35 additions & 1 deletion crates/blockchain/blockchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,10 @@ pub struct Blockchain {
merkle_pool: rayon::ThreadPool,
}

/// Default min-tip floor (wei). Matches geth's mempool `PriceLimit = 1 wei`.
/// Effectively just rejects zero-tip transactions at admission.
pub const DEFAULT_MIN_TIP_WEI: u64 = 1;

/// Configuration options for the blockchain.
#[derive(Debug, Clone)]
pub struct BlockchainOptions {
Expand All @@ -229,6 +233,10 @@ pub struct BlockchainOptions {
/// warmer thread and the executor. Set to false (via `--no-precompile-cache`) to
/// disable the cache for benchmarking purposes.
pub precompile_cache_enabled: bool,
/// Minimum effective priority fee (in wei) required for a transaction to be
/// admitted into the mempool. Transactions below this floor are rejected at
/// admission. Set to 0 to disable the floor.
pub min_tip_wei: u64,
}

impl Default for BlockchainOptions {
Expand All @@ -240,6 +248,7 @@ impl Default for BlockchainOptions {
max_blobs_per_block: None,
precompute_witnesses: false,
precompile_cache_enabled: true,
min_tip_wei: DEFAULT_MIN_TIP_WEI,
}
}
}
Expand Down Expand Up @@ -342,13 +351,20 @@ impl Blockchain {
}
}

/// Test-permissive `Blockchain` constructor. Mirrors `BlockchainOptions::default`
/// but disables admission-policy gates (e.g. the min-tip floor) so that
/// unrelated tests don't need to set every mempool option explicitly.
pub fn default_with_store(store: Store) -> Self {
let options = BlockchainOptions {
min_tip_wei: 0,
..BlockchainOptions::default()
};
Self {
storage: store,
mempool: Mempool::new(MAX_MEMPOOL_SIZE_DEFAULT),
is_synced: AtomicBool::new(false),
payloads: Arc::new(TokioMutex::new(Vec::new())),
options: BlockchainOptions::default(),
options,
merkle_pool: Self::build_merkle_pool(),
}
}
Expand Down Expand Up @@ -2505,6 +2521,24 @@ impl Blockchain {
return Err(MempoolError::TxTipAboveFeeCapError);
}

// Admission-time minimum tip floor. Compares the raw tip cap
// (`max_priority_fee_per_gas` for typed txs, `gas_price` for legacy)
// against `min_tip_wei`, matching geth's `PriceLimit` check on
// `tx.GasTipCap()` and reth's check on `max_priority_fee_per_gas`.
// Using the raw tip cap keeps the admission decision independent of
// the current base fee, so a tx that paid the floor at admission
// doesn't get reclassified as under-floor when base fee oscillates.
// A floor of 0 disables the check.
if self.options.min_tip_wei > 0 {
let tip_cap = u64::try_from(tx.gas_tip_cap()).unwrap_or(u64::MAX);
if tip_cap < self.options.min_tip_wei {
return Err(MempoolError::TipBelowMinimum {
actual: tip_cap,
limit: self.options.min_tip_wei,
});
}
}

// Check that the gas limit covers the gas needs for transaction metadata.
if tx.gas_limit() < mempool::transaction_intrinsic_gas(tx, &header, &config)? {
return Err(MempoolError::TxIntrinsicGasCostAboveLimitError);
Expand Down
2 changes: 2 additions & 0 deletions crates/blockchain/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ pub enum MempoolError {
TxMaxInitCodeSizeError,
#[error("Transaction encoded size ({actual} bytes) exceeds the {limit}-byte limit")]
TxSizeExceeded { actual: usize, limit: usize },
#[error("Tip cap {actual} wei below the configured minimum of {limit} wei")]
TipBelowMinimum { actual: u64, limit: u64 },
#[error("Transaction gas limit exceeded")]
TxGasLimitExceededError,
#[error(
Expand Down
7 changes: 3 additions & 4 deletions crates/common/types/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ pub const VERSIONED_HASH_VERSION_KZG: u8 = 0x01; // Defined in [EIP-4844](https:
/// Minimum tip, obtained from geth's default miner config (https://github.com/ethereum/go-ethereum/blob/f750117ad19d623622cc4a46ea361a716ba7407e/miner/miner.go#L56)
///
/// Scope: this constant is consumed only by the RPC gas-price estimators
/// (`eth_gasPrice`, `eth_maxPriorityFeePerGas`). It is NOT a mempool
/// admission gate — zero-tip transactions are currently admitted.
///
/// TODO: This should be configurable along with the tip filter on https://github.com/lambdaclass/ethrex/issues/680
/// (`eth_gasPrice`, `eth_maxPriorityFeePerGas`). The mempool admission
/// floor is a separate, lower default (see
/// `ethrex_blockchain::DEFAULT_MIN_TIP_WEI`).
pub const MIN_GAS_TIP: u64 = 1000000;

// Blob size related
Expand Down
6 changes: 6 additions & 0 deletions docs/CLI.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ Node options:
[env: ETHREX_MEMPOOL_MAX_SIZE=]
[default: 10000]

--mempool.min-tip <MIN_TIP_WEI>
Minimum priority-fee cap (in wei) required for a transaction to be admitted into the mempool. Compared against the raw tip cap: `max_priority_fee_per_gas` for typed transactions, `gas_price` for legacy transactions (independent of current base fee, so admission stays stable as base fee oscillates). Set to 0 to disable the floor.

[env: ETHREX_MEMPOOL_MIN_TIP=]
[default: 1]

--precompute-witnesses
Once synced, computes execution witnesses upon receiving newPayload messages and stores them in local storage

Expand Down
Loading
Loading