feat: add NoopTransactionPool impl (#3536)

This commit is contained in:
Matthias Seitz
2023-07-03 13:31:47 +02:00
committed by GitHub
parent e0748f7415
commit d80c8a7b5b
4 changed files with 212 additions and 36 deletions

View File

@ -115,18 +115,20 @@ pub use crate::{
},
};
mod config;
pub mod error;
mod identifier;
pub mod maintain;
pub mod metrics;
mod ordering;
pub mod noop;
pub mod pool;
mod traits;
pub mod validate;
mod config;
mod identifier;
mod ordering;
mod traits;
#[cfg(any(test, feature = "test-utils"))]
/// Common test helpers for mocking A pool
/// Common test helpers for mocking a pool
pub mod test_utils;
// TX_SLOT_SIZE is used to calculate how many data slots a single transaction

View File

@ -0,0 +1,195 @@
//! A transaction pool implementation that does nothing.
//!
//! This is useful for wiring components together that don't require an actual pool but still need
//! to be generic over it.
use crate::{
error::PoolError, AllPoolTransactions, BestTransactions, BlockInfo, NewTransactionEvent,
PoolResult, PoolSize, PoolTransaction, PooledTransaction, PropagatedTransactions,
TransactionEvents, TransactionOrigin, TransactionPool, TransactionValidationOutcome,
TransactionValidator, ValidPoolTransaction,
};
use reth_primitives::{Address, TxHash};
use std::{marker::PhantomData, sync::Arc};
use tokio::sync::{mpsc, mpsc::Receiver};
/// A [`TransactionPool`] implementation that does nothing.
///
/// All transactions are rejected and no events are emitted.
/// This type will never hold any transactions and is only useful for wiring components together.
#[derive(Debug, Clone, Default)]
#[non_exhaustive]
pub struct NoopTransactionPool;
#[async_trait::async_trait]
impl TransactionPool for NoopTransactionPool {
type Transaction = PooledTransaction;
fn pool_size(&self) -> PoolSize {
Default::default()
}
fn block_info(&self) -> BlockInfo {
BlockInfo {
last_seen_block_hash: Default::default(),
last_seen_block_number: 0,
pending_basefee: 0,
}
}
async fn add_transaction_and_subscribe(
&self,
_origin: TransactionOrigin,
transaction: Self::Transaction,
) -> PoolResult<TransactionEvents> {
let hash = *transaction.hash();
Err(PoolError::Other(hash, Box::new(NoopInsertError::new(transaction))))
}
async fn add_transaction(
&self,
_origin: TransactionOrigin,
transaction: Self::Transaction,
) -> PoolResult<TxHash> {
let hash = *transaction.hash();
Err(PoolError::Other(hash, Box::new(NoopInsertError::new(transaction))))
}
async fn add_transactions(
&self,
_origin: TransactionOrigin,
transactions: Vec<Self::Transaction>,
) -> PoolResult<Vec<PoolResult<TxHash>>> {
Ok(transactions
.into_iter()
.map(|transaction| {
let hash = *transaction.hash();
Err(PoolError::Other(hash, Box::new(NoopInsertError::new(transaction))))
})
.collect())
}
fn transaction_event_listener(&self, _tx_hash: TxHash) -> Option<TransactionEvents> {
None
}
fn pending_transactions_listener(&self) -> Receiver<TxHash> {
mpsc::channel(1).1
}
fn transactions_listener(&self) -> Receiver<NewTransactionEvent<Self::Transaction>> {
mpsc::channel(1).1
}
fn pooled_transaction_hashes(&self) -> Vec<TxHash> {
vec![]
}
fn pooled_transaction_hashes_max(&self, _max: usize) -> Vec<TxHash> {
vec![]
}
fn pooled_transactions(&self) -> Vec<Arc<ValidPoolTransaction<Self::Transaction>>> {
vec![]
}
fn pooled_transactions_max(
&self,
_max: usize,
) -> Vec<Arc<ValidPoolTransaction<Self::Transaction>>> {
vec![]
}
fn best_transactions(
&self,
) -> Box<dyn BestTransactions<Item = Arc<ValidPoolTransaction<Self::Transaction>>>> {
Box::new(std::iter::empty())
}
fn pending_transactions(&self) -> Vec<Arc<ValidPoolTransaction<Self::Transaction>>> {
vec![]
}
fn queued_transactions(&self) -> Vec<Arc<ValidPoolTransaction<Self::Transaction>>> {
vec![]
}
fn all_transactions(&self) -> AllPoolTransactions<Self::Transaction> {
AllPoolTransactions::default()
}
fn remove_transactions(
&self,
_hashes: impl IntoIterator<Item = TxHash>,
) -> Vec<Arc<ValidPoolTransaction<Self::Transaction>>> {
vec![]
}
fn retain_unknown(&self, _hashes: &mut Vec<TxHash>) {}
fn get(&self, _tx_hash: &TxHash) -> Option<Arc<ValidPoolTransaction<Self::Transaction>>> {
None
}
fn get_all(
&self,
_txs: impl IntoIterator<Item = TxHash>,
) -> Vec<Arc<ValidPoolTransaction<Self::Transaction>>> {
vec![]
}
fn on_propagated(&self, _txs: PropagatedTransactions) {}
fn get_transactions_by_sender(
&self,
_sender: Address,
) -> Vec<Arc<ValidPoolTransaction<Self::Transaction>>> {
vec![]
}
}
/// A [`TransactionValidator`] that does nothing.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct NoopTransactionValidator<T>(PhantomData<T>);
#[async_trait::async_trait]
impl<T: PoolTransaction> TransactionValidator for NoopTransactionValidator<T> {
type Transaction = T;
async fn validate_transaction(
&self,
_origin: TransactionOrigin,
transaction: Self::Transaction,
) -> TransactionValidationOutcome<Self::Transaction> {
TransactionValidationOutcome::Valid {
balance: Default::default(),
state_nonce: 0,
transaction,
}
}
}
impl<T> Default for NoopTransactionValidator<T> {
fn default() -> Self {
NoopTransactionValidator(PhantomData)
}
}
/// An error that contains the transaction that failed to be inserted into the noop pool.
#[derive(Debug, Clone, thiserror::Error)]
#[error("Can't insert transaction into the noop pool that does nothing.")]
pub struct NoopInsertError {
tx: PooledTransaction,
}
impl NoopInsertError {
fn new(tx: PooledTransaction) -> Self {
Self { tx }
}
/// Returns the transaction that failed to be inserted.
pub fn into_inner(self) -> PooledTransaction {
self.tx
}
}

View File

@ -5,7 +5,8 @@ mod mock;
mod pool;
use crate::{
Pool, PoolTransaction, TransactionOrigin, TransactionValidationOutcome, TransactionValidator,
noop::NoopTransactionValidator, Pool, PoolTransaction, TransactionOrigin,
TransactionValidationOutcome, TransactionValidator,
};
use async_trait::async_trait;
pub use mock::*;
@ -18,31 +19,3 @@ pub type TestPool = Pool<NoopTransactionValidator<MockTransaction>, MockOrdering
pub fn testing_pool() -> TestPool {
Pool::new(NoopTransactionValidator::default(), MockOrdering::default(), Default::default())
}
// A [`TransactionValidator`] that does nothing.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct NoopTransactionValidator<T>(PhantomData<T>);
#[async_trait::async_trait]
impl<T: PoolTransaction> TransactionValidator for NoopTransactionValidator<T> {
type Transaction = T;
async fn validate_transaction(
&self,
origin: TransactionOrigin,
transaction: Self::Transaction,
) -> TransactionValidationOutcome<Self::Transaction> {
TransactionValidationOutcome::Valid {
balance: Default::default(),
state_nonce: 0,
transaction,
}
}
}
impl<T> Default for NoopTransactionValidator<T> {
fn default() -> Self {
NoopTransactionValidator(PhantomData)
}
}

View File

@ -220,7 +220,7 @@ pub trait TransactionPoolExt: TransactionPool {
}
/// A Helper type that bundles all transactions in the pool.
#[derive(Debug, Clone, Default)]
#[derive(Debug, Clone)]
pub struct AllPoolTransactions<T: PoolTransaction> {
/// Transactions that are ready for inclusion in the next block.
pub pending: Vec<Arc<ValidPoolTransaction<T>>>,
@ -244,6 +244,12 @@ impl<T: PoolTransaction> AllPoolTransactions<T> {
}
}
impl<T: PoolTransaction> Default for AllPoolTransactions<T> {
fn default() -> Self {
Self { pending: Default::default(), queued: Default::default() }
}
}
/// Represents a transaction that was propagated over the network.
#[derive(Debug, Clone, Eq, PartialEq, Default)]
pub struct PropagatedTransactions(pub HashMap<TxHash, Vec<PropagateKind>>);
@ -577,7 +583,7 @@ impl IntoRecoveredTransaction for PooledTransaction {
}
/// Represents the current status of the pool.
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
pub struct PoolSize {
/// Number of transactions in the _pending_ sub-pool.
pub pending: usize,