diff --git a/bin/reth/src/args/txpool_args.rs b/bin/reth/src/args/txpool_args.rs index f6c3a37bbf..9a4843d2c9 100644 --- a/bin/reth/src/args/txpool_args.rs +++ b/bin/reth/src/args/txpool_args.rs @@ -2,9 +2,9 @@ use clap::Args; use reth_transaction_pool::{ - PoolConfig, PriceBumpConfig, SubPoolLimit, DEFAULT_PRICE_BUMP, REPLACE_BLOB_PRICE_BUMP, - TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT, - TXPOOL_SUBPOOL_MAX_TXS_DEFAULT, + LocalTransactionConfig, PoolConfig, PriceBumpConfig, SubPoolLimit, DEFAULT_PRICE_BUMP, + REPLACE_BLOB_PRICE_BUMP, TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, + TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT, TXPOOL_SUBPOOL_MAX_TXS_DEFAULT, }; /// Parameters for debugging purposes @@ -43,12 +43,16 @@ pub struct TxPoolArgs { /// Price bump percentage to replace an already existing blob transaction #[arg(long = "blobpool.pricebump", default_value_t = REPLACE_BLOB_PRICE_BUMP)] pub blob_transaction_price_bump: u128, + /// Flag to disable local transaction exemptions. + #[arg(long = "txpool.nolocals")] + pub no_locals: bool, } impl TxPoolArgs { /// Returns transaction pool configuration. pub fn pool_config(&self) -> PoolConfig { PoolConfig { + local_transactions_config: LocalTransactionConfig { no_exemptions: self.no_locals }, pending_limit: SubPoolLimit { max_txs: self.pending_max_count, max_size: self.pending_max_size * 1024 * 1024, diff --git a/crates/transaction-pool/src/config.rs b/crates/transaction-pool/src/config.rs index 2e561e35fb..fae1911361 100644 --- a/crates/transaction-pool/src/config.rs +++ b/crates/transaction-pool/src/config.rs @@ -30,6 +30,9 @@ pub struct PoolConfig { pub max_account_slots: usize, /// Price bump (in %) for the transaction pool underpriced check. pub price_bumps: PriceBumpConfig, + /// How to handle locally received transactions: + /// [TransactionOrigin::Local](crate::TransactionOrigin). + pub local_transactions_config: LocalTransactionConfig, } impl Default for PoolConfig { @@ -40,6 +43,7 @@ impl Default for PoolConfig { queued_limit: Default::default(), max_account_slots: TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, price_bumps: Default::default(), + local_transactions_config: Default::default(), } } } @@ -99,3 +103,24 @@ impl Default for PriceBumpConfig { } } } + +/// Configuration options for the locally received transactions: +/// [TransactionOrigin::Local](crate::TransactionOrigin) +#[derive(Debug, Clone, Eq, PartialEq, Default)] +pub struct LocalTransactionConfig { + /// Apply no exemptions to the locally received transactions. + /// + /// This includes: + /// - available slots are limited to the configured `max_account_slots` of [PoolConfig] + /// - no price exemptions + /// - no eviction exemptions + pub no_exemptions: bool, +} + +impl LocalTransactionConfig { + /// Returns whether local transactions are not exempt from the configured limits. + #[inline] + pub fn no_local_exemptions(&self) -> bool { + self.no_exemptions + } +} diff --git a/crates/transaction-pool/src/lib.rs b/crates/transaction-pool/src/lib.rs index 84c9e15ecf..1621c6ffe1 100644 --- a/crates/transaction-pool/src/lib.rs +++ b/crates/transaction-pool/src/lib.rs @@ -155,9 +155,9 @@ use tracing::{instrument, trace}; pub use crate::{ blobstore::{BlobStore, BlobStoreError}, config::{ - PoolConfig, PriceBumpConfig, SubPoolLimit, DEFAULT_PRICE_BUMP, REPLACE_BLOB_PRICE_BUMP, - TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT, - TXPOOL_SUBPOOL_MAX_TXS_DEFAULT, + LocalTransactionConfig, PoolConfig, PriceBumpConfig, SubPoolLimit, DEFAULT_PRICE_BUMP, + REPLACE_BLOB_PRICE_BUMP, TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, + TXPOOL_SUBPOOL_MAX_SIZE_MB_DEFAULT, TXPOOL_SUBPOOL_MAX_TXS_DEFAULT, }, error::PoolResult, ordering::{CoinbaseTipOrdering, Priority, TransactionOrdering}, diff --git a/crates/transaction-pool/src/pool/txpool.rs b/crates/transaction-pool/src/pool/txpool.rs index 046af47611..dfc2bf6c7c 100644 --- a/crates/transaction-pool/src/pool/txpool.rs +++ b/crates/transaction-pool/src/pool/txpool.rs @@ -1,6 +1,6 @@ //! The internal transaction pool implementation. use crate::{ - config::TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER, + config::{LocalTransactionConfig, TXPOOL_MAX_ACCOUNT_SLOTS_PER_SENDER}, error::{Eip4844PoolTransactionError, InvalidPoolTransactionError, PoolError, PoolErrorKind}, identifier::{SenderId, TransactionId}, metrics::TxPoolMetrics, @@ -918,6 +918,8 @@ pub(crate) struct AllTransactions { pending_fees: PendingFees, /// Configured price bump settings for replacements price_bumps: PriceBumpConfig, + /// How to handle [TransactionOrigin::Local](crate::TransactionOrigin) transactions. + local_transactions_config: LocalTransactionConfig, } impl AllTransactions { @@ -926,6 +928,7 @@ impl AllTransactions { Self { max_account_slots: config.max_account_slots, price_bumps: config.price_bumps, + local_transactions_config: config.local_transactions_config.clone(), ..Default::default() } } @@ -1274,7 +1277,7 @@ impl AllTransactions { &self, transaction: ValidPoolTransaction, ) -> Result, InsertErr> { - if !transaction.origin.is_local() { + if !transaction.origin.is_local() || self.local_transactions_config.no_local_exemptions() { let current_txs = self.tx_counter.get(&transaction.sender_id()).copied().unwrap_or_default(); if current_txs >= self.max_account_slots { @@ -1664,6 +1667,7 @@ impl Default for AllTransactions { last_seen_block_hash: Default::default(), pending_fees: Default::default(), price_bumps: Default::default(), + local_transactions_config: Default::default(), } } } diff --git a/crates/transaction-pool/src/validate/eth.rs b/crates/transaction-pool/src/validate/eth.rs index 169f17263e..340258c2f7 100644 --- a/crates/transaction-pool/src/validate/eth.rs +++ b/crates/transaction-pool/src/validate/eth.rs @@ -5,8 +5,8 @@ use crate::{ error::{Eip4844PoolTransactionError, InvalidPoolTransactionError}, traits::TransactionOrigin, validate::{ValidTransaction, ValidationTask, MAX_INIT_CODE_SIZE, TX_MAX_SIZE}, - EthBlobTransactionSidecar, EthPoolTransaction, PoolTransaction, TransactionValidationOutcome, - TransactionValidationTaskExecutor, TransactionValidator, + EthBlobTransactionSidecar, EthPoolTransaction, LocalTransactionConfig, PoolTransaction, + TransactionValidationOutcome, TransactionValidationTaskExecutor, TransactionValidator, }; use reth_primitives::{ constants::{ @@ -124,6 +124,8 @@ where propagate_local_transactions: bool, /// Stores the setup and parameters needed for validating KZG proofs. kzg_settings: Arc, + /// How to handle [TransactionOrigin::Local](TransactionOrigin) transactions. + local_transactions_config: LocalTransactionConfig, /// Marker for the transaction type _marker: PhantomData, } @@ -235,7 +237,7 @@ where // Drop non-local transactions with a fee lower than the configured fee for acceptance into // the pool. - if !origin.is_local() && + if (!origin.is_local() || self.local_transactions_config.no_local_exemptions()) && transaction.is_eip1559() && transaction.max_priority_fee_per_gas() < self.minimum_priority_fee { @@ -484,6 +486,8 @@ pub struct EthTransactionValidatorBuilder { /// Stores the setup and parameters needed for validating KZG proofs. kzg_settings: Arc, + /// How to handle [TransactionOrigin::Local](TransactionOrigin) transactions. + local_transactions_config: LocalTransactionConfig, } impl EthTransactionValidatorBuilder { @@ -500,6 +504,7 @@ impl EthTransactionValidatorBuilder { // default to true, can potentially take this as a param in the future propagate_local_transactions: true, kzg_settings: Arc::clone(&MAINNET_KZG_TRUSTED_SETUP), + local_transactions_config: Default::default(), // by default all transaction types are allowed eip2718: true, @@ -519,6 +524,15 @@ impl EthTransactionValidatorBuilder { self.set_cancun(false) } + /// Whether to allow exemptions for local transaction exemptions. + pub fn set_local_transactions_config( + mut self, + local_transactions_config: LocalTransactionConfig, + ) -> Self { + self.local_transactions_config = local_transactions_config; + self + } + /// Set the Cancun fork. pub fn set_cancun(mut self, cancun: bool) -> Self { self.cancun = cancun; @@ -624,6 +638,7 @@ impl EthTransactionValidatorBuilder { minimum_priority_fee, propagate_local_transactions, kzg_settings, + local_transactions_config, .. } = self; @@ -642,6 +657,7 @@ impl EthTransactionValidatorBuilder { propagate_local_transactions, blob_store: Box::new(blob_store), kzg_settings, + local_transactions_config, _marker: Default::default(), };