Skip to content

Commit

Permalink
feat: add NoopTransactionPool impl (#3536)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse authored Jul 3, 2023
1 parent e0748f7 commit d80c8a7
Show file tree
Hide file tree
Showing 4 changed files with 212 additions and 36 deletions.
12 changes: 7 additions & 5 deletions crates/transaction-pool/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
195 changes: 195 additions & 0 deletions crates/transaction-pool/src/noop.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
31 changes: 2 additions & 29 deletions crates/transaction-pool/src/test_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand All @@ -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)
}
}
10 changes: 8 additions & 2 deletions crates/transaction-pool/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>>>,
Expand All @@ -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>>);
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit d80c8a7

Please sign in to comment.