diff --git a/crates/transaction-pool/src/error.rs b/crates/transaction-pool/src/error.rs index be74f99861..3f08c4f102 100644 --- a/crates/transaction-pool/src/error.rs +++ b/crates/transaction-pool/src/error.rs @@ -121,4 +121,7 @@ pub enum InvalidPoolTransactionError { /// making the transaction invalid, rather a DOS protection. #[error("Input data too large")] OversizedData(usize, usize), + /// Thrown if the transaction's fee is below the minimum fee + #[error("transaction underpriced")] + Underpriced, } diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 0aad8d2fd7..8df307dfa7 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -1,7 +1,7 @@ use crate::{error::PoolResult, pool::state::SubPool, validate::ValidPoolTransaction}; use reth_primitives::{ Address, FromRecoveredTransaction, IntoRecoveredTransaction, PeerId, Transaction, - TransactionKind, TransactionSignedEcRecovered, TxHash, H256, U256, + TransactionKind, TransactionSignedEcRecovered, TxHash, EIP1559_TX_TYPE_ID, H256, U256, }; use reth_rlp::Encodable; use std::{collections::HashMap, fmt, sync::Arc}; @@ -314,6 +314,11 @@ pub trait PoolTransaction: /// Returns the transaction type fn tx_type(&self) -> u8; + /// Returns true if the transaction is an EIP-1559 transaction. + fn is_eip1559(&self) -> bool { + self.tx_type() == EIP1559_TX_TYPE_ID + } + /// Returns the length of the rlp encoded object fn encoded_length(&self) -> usize; diff --git a/crates/transaction-pool/src/validate.rs b/crates/transaction-pool/src/validate.rs index 42fd4a0122..67f986cea4 100644 --- a/crates/transaction-pool/src/validate.rs +++ b/crates/transaction-pool/src/validate.rs @@ -96,9 +96,9 @@ pub struct EthTransactionValidator { /// Fork indicator whether we are using EIP-1559 type transactions. eip1559: bool, /// The current max gas limit - current_max_gas_limit: u64, - /// Current base fee. - base_fee: Option, + block_gas_limit: u64, + /// Minimum priority fee to enforce for acceptance into the pool. + minimum_priority_fee: Option, /// Marker for the transaction type _marker: PhantomData, } @@ -116,8 +116,8 @@ impl EthTransactionValidator { shanghai: true, eip2718: true, eip1559: true, - current_max_gas_limit: 30_000_000, - base_fee: None, + block_gas_limit: 30_000_000, + minimum_priority_fee: None, _marker: Default::default(), } } @@ -191,11 +191,11 @@ where } // Checks for gas limit - if transaction.gas_limit() > self.current_max_gas_limit { + if transaction.gas_limit() > self.block_gas_limit { let gas_limit = transaction.gas_limit(); return TransactionValidationOutcome::Invalid( transaction, - InvalidPoolTransactionError::ExceedsGasLimit(gas_limit, self.current_max_gas_limit), + InvalidPoolTransactionError::ExceedsGasLimit(gas_limit, self.block_gas_limit), ) } @@ -207,11 +207,15 @@ where ) } - // Drop non-local transactions under our own minimal accepted gas price or tip - if !origin.is_local() && transaction.max_fee_per_gas() < self.base_fee { + // Drop non-local transactions with a fee lower than the configured fee for acceptance into + // the pool. + if !origin.is_local() && + transaction.is_eip1559() && + transaction.max_priority_fee_per_gas() < self.minimum_priority_fee + { return TransactionValidationOutcome::Invalid( transaction, - InvalidTransactionError::MaxFeeLessThenBaseFee.into(), + InvalidPoolTransactionError::Underpriced, ) }