mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat(txpool): add gas limit check when inserting new transactions (#780)
* Add gas limit check when inserting transaction Part of the code was copied from an issue comment: https://github.com/paradigmxyz/reth/issues/76#issuecomment-1345281800 Co-authored-by: Eduardo <96149783+elprogramadorgt@users.noreply.github.com> * Add test for gas limit check Co-authored-by: Eduardo <96149783+elprogramadorgt@users.noreply.github.com>
This commit is contained in:
@ -21,6 +21,10 @@ pub enum PoolError {
|
||||
/// respect the size limits of the pool.
|
||||
#[error("[{0:?}] Transaction discarded outright due to pool size constraints.")]
|
||||
DiscardedOnInsert(TxHash),
|
||||
/// Thrown when a new transaction is added to the pool, but then immediately discarded to
|
||||
/// respect the size limits of the pool.
|
||||
#[error("[{0:?}] Transaction's gas limit {1} exceeds block's gas limit {2}.")]
|
||||
TxExceedsGasLimit(TxHash, u64, u64),
|
||||
}
|
||||
|
||||
// === impl PoolError ===
|
||||
@ -33,6 +37,7 @@ impl PoolError {
|
||||
PoolError::ProtocolFeeCapTooLow(hash, _) => hash,
|
||||
PoolError::SpammerExceededCapacity(_, hash) => hash,
|
||||
PoolError::DiscardedOnInsert(hash) => hash,
|
||||
PoolError::TxExceedsGasLimit(hash, _, _) => hash,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,6 +256,15 @@ impl<T: TransactionOrdering> TxPool<T> {
|
||||
*transaction.hash(),
|
||||
))
|
||||
}
|
||||
InsertErr::TxGasLimitMoreThanAvailableBlockGas {
|
||||
transaction,
|
||||
block_gas_limit,
|
||||
tx_gas_limit,
|
||||
} => Err(PoolError::TxExceedsGasLimit(
|
||||
*transaction.hash(),
|
||||
block_gas_limit,
|
||||
tx_gas_limit,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -770,6 +779,7 @@ impl<T: PoolTransaction> AllTransactions<T> {
|
||||
/// This will enforce all additional rules in the context of this pool, such as:
|
||||
/// - Spam protection: reject new non-local transaction from a sender that exhausted its slot
|
||||
/// capacity.
|
||||
/// - Gas limit: reject transactions if they exceed a block's maximum gas.
|
||||
fn ensure_valid(
|
||||
&self,
|
||||
transaction: ValidPoolTransaction<T>,
|
||||
@ -783,6 +793,13 @@ impl<T: PoolTransaction> AllTransactions<T> {
|
||||
})
|
||||
}
|
||||
}
|
||||
if transaction.gas_limit() > self.block_gas_limit {
|
||||
return Err(InsertErr::TxGasLimitMoreThanAvailableBlockGas {
|
||||
block_gas_limit: self.block_gas_limit,
|
||||
tx_gas_limit: transaction.gas_limit(),
|
||||
transaction: Arc::new(transaction),
|
||||
})
|
||||
}
|
||||
Ok(transaction)
|
||||
}
|
||||
|
||||
@ -1006,6 +1023,12 @@ pub(crate) enum InsertErr<T: PoolTransaction> {
|
||||
///
|
||||
/// The sender can be considered a spammer at this point.
|
||||
ExceededSenderTransactionsCapacity { transaction: Arc<ValidPoolTransaction<T>> },
|
||||
/// Transaction gas limit exceeds block's gas limit
|
||||
TxGasLimitMoreThanAvailableBlockGas {
|
||||
transaction: Arc<ValidPoolTransaction<T>>,
|
||||
block_gas_limit: u64,
|
||||
tx_gas_limit: u64,
|
||||
},
|
||||
}
|
||||
|
||||
/// Transaction was successfully inserted into the pool
|
||||
@ -1340,4 +1363,19 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reject_tx_over_gas_limit() {
|
||||
let on_chain_balance = U256::from(1_000);
|
||||
let on_chain_nonce = 0;
|
||||
let mut f = MockTransactionFactory::default();
|
||||
let mut pool = AllTransactions::default();
|
||||
|
||||
let tx = MockTransaction::eip1559().with_gas_limit(30_000_001);
|
||||
|
||||
assert!(matches!(
|
||||
pool.insert_tx(f.validated(tx), on_chain_balance, on_chain_nonce),
|
||||
Err(InsertErr::TxGasLimitMoreThanAvailableBlockGas { .. })
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ pub trait TransactionValidator: Send + Sync {
|
||||
) -> TransactionValidationOutcome<Self::Transaction>;
|
||||
}
|
||||
|
||||
/// A valida transaction in the pool.
|
||||
/// A valid transaction in the pool.
|
||||
pub struct ValidPoolTransaction<T: PoolTransaction> {
|
||||
/// The transaction
|
||||
pub transaction: T,
|
||||
@ -64,7 +64,7 @@ pub struct ValidPoolTransaction<T: PoolTransaction> {
|
||||
pub transaction_id: TransactionId,
|
||||
/// Whether to propagate the transaction.
|
||||
pub propagate: bool,
|
||||
/// Total cost of the transaction: `feeCap x gasLimit + transferred_value`.
|
||||
/// Total cost of the transaction: `feeCap x gasLimit + transferredValue`.
|
||||
pub cost: U256,
|
||||
/// Timestamp when this was added to the pool.
|
||||
pub timestamp: Instant,
|
||||
|
||||
Reference in New Issue
Block a user