mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
refactor(tx-pool): add enum InvalidKind to mark_invalid (#12845)
This commit is contained in:
@ -27,13 +27,13 @@ use reth_payload_builder_primitives::PayloadBuilderError;
|
||||
use reth_payload_primitives::PayloadBuilderAttributes;
|
||||
use reth_primitives::{
|
||||
proofs::{self},
|
||||
Block, BlockBody, BlockExt, EthereumHardforks, Receipt,
|
||||
Block, BlockBody, BlockExt, EthereumHardforks, InvalidTransactionError, Receipt,
|
||||
};
|
||||
use reth_provider::{ChainSpecProvider, StateProviderFactory};
|
||||
use reth_revm::database::StateProviderDatabase;
|
||||
use reth_transaction_pool::{
|
||||
noop::NoopTransactionPool, BestTransactions, BestTransactionsAttributes, TransactionPool,
|
||||
ValidPoolTransaction,
|
||||
error::InvalidPoolTransactionError, noop::NoopTransactionPool, BestTransactions,
|
||||
BestTransactionsAttributes, TransactionPool, ValidPoolTransaction,
|
||||
};
|
||||
use reth_trie::HashedPostState;
|
||||
use revm::{
|
||||
@ -228,7 +228,10 @@ where
|
||||
// we can't fit this transaction into the block, so we need to mark it as invalid
|
||||
// which also removes all dependent transaction from the iterator before we can
|
||||
// continue
|
||||
best_txs.mark_invalid(&pool_tx);
|
||||
best_txs.mark_invalid(
|
||||
&pool_tx,
|
||||
InvalidPoolTransactionError::ExceedsGasLimit(pool_tx.gas_limit(), block_gas_limit),
|
||||
);
|
||||
continue
|
||||
}
|
||||
|
||||
@ -250,7 +253,13 @@ where
|
||||
// the iterator. This is similar to the gas limit condition
|
||||
// for regular transactions above.
|
||||
trace!(target: "payload_builder", tx=?tx.hash, ?sum_blob_gas_used, ?tx_blob_gas, "skipping blob transaction because it would exceed the max data gas per block");
|
||||
best_txs.mark_invalid(&pool_tx);
|
||||
best_txs.mark_invalid(
|
||||
&pool_tx,
|
||||
InvalidPoolTransactionError::ExceedsGasLimit(
|
||||
tx_blob_gas,
|
||||
MAX_DATA_GAS_PER_BLOCK,
|
||||
),
|
||||
);
|
||||
continue
|
||||
}
|
||||
}
|
||||
@ -270,7 +279,12 @@ where
|
||||
// if the transaction is invalid, we can skip it and all of its
|
||||
// descendants
|
||||
trace!(target: "payload_builder", %err, ?tx, "skipping invalid transaction and its descendants");
|
||||
best_txs.mark_invalid(&pool_tx);
|
||||
best_txs.mark_invalid(
|
||||
&pool_tx,
|
||||
InvalidPoolTransactionError::Consensus(
|
||||
InvalidTransactionError::TxTypeNotSupported,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
continue
|
||||
|
||||
@ -17,8 +17,8 @@ use reth_evm::{
|
||||
};
|
||||
use reth_execution_types::ExecutionOutcome;
|
||||
use reth_primitives::{
|
||||
proofs::calculate_transaction_root, Block, BlockBody, BlockExt, Receipt,
|
||||
SealedBlockWithSenders, SealedHeader, TransactionSignedEcRecovered,
|
||||
proofs::calculate_transaction_root, Block, BlockBody, BlockExt, InvalidTransactionError,
|
||||
Receipt, SealedBlockWithSenders, SealedHeader, TransactionSignedEcRecovered,
|
||||
};
|
||||
use reth_provider::{
|
||||
BlockReader, BlockReaderIdExt, ChainSpecProvider, EvmEnvProvider, ProviderError,
|
||||
@ -32,7 +32,9 @@ use reth_revm::{
|
||||
},
|
||||
};
|
||||
use reth_rpc_eth_types::{EthApiError, PendingBlock, PendingBlockEnv, PendingBlockEnvOrigin};
|
||||
use reth_transaction_pool::{BestTransactionsAttributes, TransactionPool};
|
||||
use reth_transaction_pool::{
|
||||
error::InvalidPoolTransactionError, BestTransactionsAttributes, TransactionPool,
|
||||
};
|
||||
use reth_trie::HashedPostState;
|
||||
use revm::{db::states::bundle_state::BundleRetention, DatabaseCommit, State};
|
||||
use std::time::{Duration, Instant};
|
||||
@ -292,7 +294,13 @@ pub trait LoadPendingBlock:
|
||||
// we can't fit this transaction into the block, so we need to mark it as invalid
|
||||
// which also removes all dependent transaction from the iterator before we can
|
||||
// continue
|
||||
best_txs.mark_invalid(&pool_tx);
|
||||
best_txs.mark_invalid(
|
||||
&pool_tx,
|
||||
InvalidPoolTransactionError::ExceedsGasLimit(
|
||||
pool_tx.gas_limit(),
|
||||
block_gas_limit,
|
||||
),
|
||||
);
|
||||
continue
|
||||
}
|
||||
|
||||
@ -300,7 +308,12 @@ pub trait LoadPendingBlock:
|
||||
// we don't want to leak any state changes made by private transactions, so we mark
|
||||
// them as invalid here which removes all dependent transactions from the iterator
|
||||
// before we can continue
|
||||
best_txs.mark_invalid(&pool_tx);
|
||||
best_txs.mark_invalid(
|
||||
&pool_tx,
|
||||
InvalidPoolTransactionError::Consensus(
|
||||
InvalidTransactionError::TxTypeNotSupported,
|
||||
),
|
||||
);
|
||||
continue
|
||||
}
|
||||
|
||||
@ -316,7 +329,13 @@ pub trait LoadPendingBlock:
|
||||
// invalid, which removes its dependent transactions from
|
||||
// the iterator. This is similar to the gas limit condition
|
||||
// for regular transactions above.
|
||||
best_txs.mark_invalid(&pool_tx);
|
||||
best_txs.mark_invalid(
|
||||
&pool_tx,
|
||||
InvalidPoolTransactionError::ExceedsGasLimit(
|
||||
tx_blob_gas,
|
||||
MAX_DATA_GAS_PER_BLOCK,
|
||||
),
|
||||
);
|
||||
continue
|
||||
}
|
||||
}
|
||||
@ -340,7 +359,12 @@ pub trait LoadPendingBlock:
|
||||
} else {
|
||||
// if the transaction is invalid, we can skip it and all of its
|
||||
// descendants
|
||||
best_txs.mark_invalid(&pool_tx);
|
||||
best_txs.mark_invalid(
|
||||
&pool_tx,
|
||||
InvalidPoolTransactionError::Consensus(
|
||||
InvalidTransactionError::TxTypeNotSupported,
|
||||
),
|
||||
);
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@ -52,7 +52,6 @@ bitflags.workspace = true
|
||||
auto_impl.workspace = true
|
||||
smallvec.workspace = true
|
||||
|
||||
|
||||
# testing
|
||||
rand = { workspace = true, optional = true }
|
||||
paste = { workspace = true, optional = true }
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use crate::{
|
||||
error::{Eip4844PoolTransactionError, InvalidPoolTransactionError},
|
||||
identifier::{SenderId, TransactionId},
|
||||
pool::pending::PendingTransaction,
|
||||
PoolTransaction, TransactionOrdering, ValidPoolTransaction,
|
||||
@ -6,7 +7,7 @@ use crate::{
|
||||
use alloy_primitives::Address;
|
||||
use core::fmt;
|
||||
use reth_payload_util::PayloadTransactions;
|
||||
use reth_primitives::TransactionSignedEcRecovered;
|
||||
use reth_primitives::{InvalidTransactionError, TransactionSignedEcRecovered};
|
||||
use std::{
|
||||
collections::{BTreeMap, BTreeSet, HashSet, VecDeque},
|
||||
sync::Arc,
|
||||
@ -27,8 +28,8 @@ pub(crate) struct BestTransactionsWithFees<T: TransactionOrdering> {
|
||||
}
|
||||
|
||||
impl<T: TransactionOrdering> crate::traits::BestTransactions for BestTransactionsWithFees<T> {
|
||||
fn mark_invalid(&mut self, tx: &Self::Item) {
|
||||
BestTransactions::mark_invalid(&mut self.best, tx)
|
||||
fn mark_invalid(&mut self, tx: &Self::Item, kind: InvalidPoolTransactionError) {
|
||||
BestTransactions::mark_invalid(&mut self.best, tx, kind)
|
||||
}
|
||||
|
||||
fn no_updates(&mut self) {
|
||||
@ -60,7 +61,11 @@ impl<T: TransactionOrdering> Iterator for BestTransactionsWithFees<T> {
|
||||
{
|
||||
return Some(best);
|
||||
}
|
||||
crate::traits::BestTransactions::mark_invalid(self, &best);
|
||||
crate::traits::BestTransactions::mark_invalid(
|
||||
self,
|
||||
&best,
|
||||
InvalidPoolTransactionError::Underpriced,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -95,7 +100,11 @@ pub(crate) struct BestTransactions<T: TransactionOrdering> {
|
||||
|
||||
impl<T: TransactionOrdering> BestTransactions<T> {
|
||||
/// Mark the transaction and it's descendants as invalid.
|
||||
pub(crate) fn mark_invalid(&mut self, tx: &Arc<ValidPoolTransaction<T::Transaction>>) {
|
||||
pub(crate) fn mark_invalid(
|
||||
&mut self,
|
||||
tx: &Arc<ValidPoolTransaction<T::Transaction>>,
|
||||
_kind: InvalidPoolTransactionError,
|
||||
) {
|
||||
self.invalid.insert(tx.sender_id());
|
||||
}
|
||||
|
||||
@ -154,8 +163,8 @@ impl<T: TransactionOrdering> BestTransactions<T> {
|
||||
}
|
||||
|
||||
impl<T: TransactionOrdering> crate::traits::BestTransactions for BestTransactions<T> {
|
||||
fn mark_invalid(&mut self, tx: &Self::Item) {
|
||||
Self::mark_invalid(self, tx)
|
||||
fn mark_invalid(&mut self, tx: &Self::Item, kind: InvalidPoolTransactionError) {
|
||||
Self::mark_invalid(self, tx, kind)
|
||||
}
|
||||
|
||||
fn no_updates(&mut self) {
|
||||
@ -199,7 +208,12 @@ impl<T: TransactionOrdering> Iterator for BestTransactions<T> {
|
||||
if self.skip_blobs && best.transaction.transaction.is_eip4844() {
|
||||
// blobs should be skipped, marking them as invalid will ensure that no dependent
|
||||
// transactions are returned
|
||||
self.mark_invalid(&best.transaction)
|
||||
self.mark_invalid(
|
||||
&best.transaction,
|
||||
InvalidPoolTransactionError::Eip4844(
|
||||
Eip4844PoolTransactionError::NoEip4844Blobs,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
return Some(best.transaction)
|
||||
}
|
||||
@ -280,7 +294,10 @@ where
|
||||
if (self.predicate)(&best) {
|
||||
return Some(best)
|
||||
}
|
||||
self.best.mark_invalid(&best);
|
||||
self.best.mark_invalid(
|
||||
&best,
|
||||
InvalidPoolTransactionError::Consensus(InvalidTransactionError::TxTypeNotSupported),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -290,8 +307,8 @@ where
|
||||
I: crate::traits::BestTransactions,
|
||||
P: FnMut(&<I as Iterator>::Item) -> bool + Send,
|
||||
{
|
||||
fn mark_invalid(&mut self, tx: &Self::Item) {
|
||||
crate::traits::BestTransactions::mark_invalid(&mut self.best, tx)
|
||||
fn mark_invalid(&mut self, tx: &Self::Item, kind: InvalidPoolTransactionError) {
|
||||
crate::traits::BestTransactions::mark_invalid(&mut self.best, tx, kind)
|
||||
}
|
||||
|
||||
fn no_updates(&mut self) {
|
||||
@ -379,8 +396,8 @@ where
|
||||
I: crate::traits::BestTransactions<Item = Arc<ValidPoolTransaction<T>>>,
|
||||
T: PoolTransaction,
|
||||
{
|
||||
fn mark_invalid(&mut self, tx: &Self::Item) {
|
||||
self.inner.mark_invalid(tx)
|
||||
fn mark_invalid(&mut self, tx: &Self::Item, kind: InvalidPoolTransactionError) {
|
||||
self.inner.mark_invalid(tx, kind)
|
||||
}
|
||||
|
||||
fn no_updates(&mut self) {
|
||||
@ -450,7 +467,10 @@ mod tests {
|
||||
|
||||
// mark the first tx as invalid
|
||||
let invalid = best.independent.iter().next().unwrap();
|
||||
best.mark_invalid(&invalid.transaction.clone());
|
||||
best.mark_invalid(
|
||||
&invalid.transaction.clone(),
|
||||
InvalidPoolTransactionError::Consensus(InvalidTransactionError::TxTypeNotSupported),
|
||||
);
|
||||
|
||||
// iterator is empty
|
||||
assert!(best.next().is_none());
|
||||
@ -475,7 +495,11 @@ mod tests {
|
||||
> = Box::new(pool.best());
|
||||
|
||||
let tx = Iterator::next(&mut best).unwrap();
|
||||
crate::traits::BestTransactions::mark_invalid(&mut *best, &tx);
|
||||
crate::traits::BestTransactions::mark_invalid(
|
||||
&mut *best,
|
||||
&tx,
|
||||
InvalidPoolTransactionError::Consensus(InvalidTransactionError::TxTypeNotSupported),
|
||||
);
|
||||
assert!(Iterator::next(&mut best).is_none());
|
||||
}
|
||||
|
||||
|
||||
@ -806,7 +806,7 @@ pub trait BestTransactions: Iterator + Send {
|
||||
/// Implementers must ensure all subsequent transaction _don't_ depend on this transaction.
|
||||
/// In other words, this must remove the given transaction _and_ drain all transaction that
|
||||
/// depend on it.
|
||||
fn mark_invalid(&mut self, transaction: &Self::Item);
|
||||
fn mark_invalid(&mut self, transaction: &Self::Item, kind: InvalidPoolTransactionError);
|
||||
|
||||
/// An iterator may be able to receive additional pending transactions that weren't present it
|
||||
/// the pool when it was created.
|
||||
@ -868,8 +868,8 @@ impl<T> BestTransactions for Box<T>
|
||||
where
|
||||
T: BestTransactions + ?Sized,
|
||||
{
|
||||
fn mark_invalid(&mut self, transaction: &Self::Item) {
|
||||
(**self).mark_invalid(transaction);
|
||||
fn mark_invalid(&mut self, transaction: &Self::Item, kind: InvalidPoolTransactionError) {
|
||||
(**self).mark_invalid(transaction, kind)
|
||||
}
|
||||
|
||||
fn no_updates(&mut self) {
|
||||
@ -887,7 +887,7 @@ where
|
||||
|
||||
/// A no-op implementation that yields no transactions.
|
||||
impl<T> BestTransactions for std::iter::Empty<T> {
|
||||
fn mark_invalid(&mut self, _tx: &T) {}
|
||||
fn mark_invalid(&mut self, _tx: &T, _kind: InvalidPoolTransactionError) {}
|
||||
|
||||
fn no_updates(&mut self) {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user