refactor(txpool): simplify validator trait (#60)

* refactor(txpool): simplify validator trait

* fix docs
This commit is contained in:
Matthias Seitz
2022-10-13 20:36:15 +02:00
committed by GitHub
parent 55768a534d
commit 6b71460e7e
4 changed files with 36 additions and 50 deletions

View File

@ -1,10 +0,0 @@
//! Provides access to the chain's storage
use crate::{error::PoolError, validate::TransactionValidator};
/// The interface used to interact with the blockchain and access storage.
#[async_trait::async_trait]
pub trait PoolClient: Send + Sync + TransactionValidator {
/// Error type that can be converted to the crate's internal Error.
type Error: Into<PoolError>;
}

View File

@ -15,10 +15,10 @@
//! //!
//! The transaction pool is responsible for //! The transaction pool is responsible for
//! //!
//! - recording incoming transactions //! - recording incoming transactions
//! - providing existing transactions //! - providing existing transactions
//! - ordering and providing the best transactions for block production //! - ordering and providing the best transactions for block production
//! - monitoring memory footprint and enforce pool size limits //! - monitoring memory footprint and enforce pool size limits
//! //!
//! ## Assumptions //! ## Assumptions
//! //!
@ -51,9 +51,9 @@
//! //!
//! Once a new block is mined, the pool needs to be updated with a changeset in order to: //! Once a new block is mined, the pool needs to be updated with a changeset in order to:
//! //!
//! - remove mined transactions //! - remove mined transactions
//! - update using account changes: balance changes //! - update using account changes: balance changes
//! - base fee updates //! - base fee updates
//! //!
//! ## Implementation details //! ## Implementation details
//! //!
@ -76,7 +76,6 @@
//! that provides the `TransactionPool` interface. //! that provides the `TransactionPool` interface.
pub use crate::{ pub use crate::{
client::PoolClient,
config::PoolConfig, config::PoolConfig,
ordering::TransactionOrdering, ordering::TransactionOrdering,
traits::{BestTransactions, NewBlockEvent, PoolTransaction, TransactionPool}, traits::{BestTransactions, NewBlockEvent, PoolTransaction, TransactionPool},
@ -89,7 +88,6 @@ use futures::channel::mpsc::Receiver;
use reth_primitives::{BlockID, TxHash, U256, U64}; use reth_primitives::{BlockID, TxHash, U256, U64};
use std::{collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
mod client;
mod config; mod config;
pub mod error; pub mod error;
mod identifier; mod identifier;
@ -102,33 +100,33 @@ mod validate;
mod test_util; mod test_util;
/// A shareable, generic, customizable `TransactionPool` implementation. /// A shareable, generic, customizable `TransactionPool` implementation.
pub struct Pool<P: PoolClient, T: TransactionOrdering> { pub struct Pool<V: TransactionValidator, T: TransactionOrdering> {
/// Arc'ed instance of the pool internals /// Arc'ed instance of the pool internals
pool: Arc<PoolInner<P, T>>, pool: Arc<PoolInner<V, T>>,
} }
// === impl Pool === // === impl Pool ===
impl<P, T> Pool<P, T> impl<V, T> Pool<V, T>
where where
P: PoolClient, V: TransactionValidator,
T: TransactionOrdering<Transaction = <P as TransactionValidator>::Transaction>, T: TransactionOrdering<Transaction = <V as TransactionValidator>::Transaction>,
{ {
/// Create a new transaction pool instance. /// Create a new transaction pool instance.
pub fn new(client: Arc<P>, ordering: Arc<T>, config: PoolConfig) -> Self { pub fn new(client: Arc<V>, ordering: Arc<T>, config: PoolConfig) -> Self {
Self { pool: Arc::new(PoolInner::new(client, ordering, config)) } Self { pool: Arc::new(PoolInner::new(client, ordering, config)) }
} }
/// Returns the wrapped pool. /// Returns the wrapped pool.
pub(crate) fn inner(&self) -> &PoolInner<P, T> { pub(crate) fn inner(&self) -> &PoolInner<V, T> {
&self.pool &self.pool
} }
/// Returns future that validates all transaction in the given iterator. /// Returns future that validates all transaction in the given iterator.
async fn validate_all( async fn validate_all(
&self, &self,
transactions: impl IntoIterator<Item = P::Transaction>, transactions: impl IntoIterator<Item = V::Transaction>,
) -> PoolResult<HashMap<TxHash, TransactionValidationOutcome<P::Transaction>>> { ) -> PoolResult<HashMap<TxHash, TransactionValidationOutcome<V::Transaction>>> {
let outcome = let outcome =
futures::future::join_all(transactions.into_iter().map(|tx| self.validate(tx))) futures::future::join_all(transactions.into_iter().map(|tx| self.validate(tx)))
.await .await
@ -141,12 +139,12 @@ where
/// Validates the given transaction /// Validates the given transaction
async fn validate( async fn validate(
&self, &self,
transaction: P::Transaction, transaction: V::Transaction,
) -> (TxHash, TransactionValidationOutcome<P::Transaction>) { ) -> (TxHash, TransactionValidationOutcome<V::Transaction>) {
let hash = *transaction.hash(); let hash = *transaction.hash();
// TODO(mattsse): this is where additional validate checks would go, like banned senders // TODO(mattsse): this is where additional validate checks would go, like banned senders
// etc... // etc...
let outcome = self.pool.client().validate_transaction(transaction).await; let outcome = self.pool.validator().validate_transaction(transaction).await;
(hash, outcome) (hash, outcome)
} }
@ -164,10 +162,10 @@ where
/// implements the `TransactionPool` interface for various transaction pool API consumers. /// implements the `TransactionPool` interface for various transaction pool API consumers.
#[async_trait::async_trait] #[async_trait::async_trait]
impl<P, T> TransactionPool for Pool<P, T> impl<V, T> TransactionPool for Pool<V, T>
where where
P: PoolClient, V: TransactionValidator,
T: TransactionOrdering<Transaction = <P as TransactionValidator>::Transaction>, T: TransactionOrdering<Transaction = <V as TransactionValidator>::Transaction>,
{ {
type Transaction = T::Transaction; type Transaction = T::Transaction;
@ -216,7 +214,7 @@ where
} }
} }
impl<P: PoolClient, O: TransactionOrdering> Clone for Pool<P, O> { impl<V: TransactionValidator, O: TransactionOrdering> Clone for Pool<V, O> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
Self { pool: Arc::clone(&self.pool) } Self { pool: Arc::clone(&self.pool) }
} }

View File

@ -69,7 +69,7 @@ use crate::{
pool::{listener::PoolEventListener, state::SubPool, txpool::TxPool}, pool::{listener::PoolEventListener, state::SubPool, txpool::TxPool},
traits::{NewTransactionEvent, PoolTransaction}, traits::{NewTransactionEvent, PoolTransaction},
validate::{TransactionValidationOutcome, ValidPoolTransaction}, validate::{TransactionValidationOutcome, ValidPoolTransaction},
PoolClient, PoolConfig, TransactionOrdering, TransactionValidator, U256, PoolConfig, TransactionOrdering, TransactionValidator, U256,
}; };
use best::BestTransactions; use best::BestTransactions;
pub use events::TransactionEvent; pub use events::TransactionEvent;
@ -89,11 +89,11 @@ mod transaction;
pub mod txpool; pub mod txpool;
/// Transaction pool internals. /// Transaction pool internals.
pub struct PoolInner<P: PoolClient, T: TransactionOrdering> { pub struct PoolInner<V: TransactionValidator, T: TransactionOrdering> {
/// Internal mapping of addresses to plain ints. /// Internal mapping of addresses to plain ints.
identifiers: RwLock<SenderIdentifiers>, identifiers: RwLock<SenderIdentifiers>,
/// Chain/Storage access. /// Transaction validation.
client: Arc<P>, validator: Arc<V>,
/// The internal pool that manages all transactions. /// The internal pool that manages all transactions.
pool: RwLock<TxPool<T>>, pool: RwLock<TxPool<T>>,
/// Pool settings. /// Pool settings.
@ -108,16 +108,16 @@ pub struct PoolInner<P: PoolClient, T: TransactionOrdering> {
// === impl PoolInner === // === impl PoolInner ===
impl<P: PoolClient, T: TransactionOrdering> PoolInner<P, T> impl<V: TransactionValidator, T: TransactionOrdering> PoolInner<V, T>
where where
P: PoolClient, V: TransactionValidator,
T: TransactionOrdering<Transaction = <P as TransactionValidator>::Transaction>, T: TransactionOrdering<Transaction = <V as TransactionValidator>::Transaction>,
{ {
/// Create a new transaction pool instance. /// Create a new transaction pool instance.
pub fn new(client: Arc<P>, ordering: Arc<T>, config: PoolConfig) -> Self { pub fn new(client: Arc<V>, ordering: Arc<T>, config: PoolConfig) -> Self {
Self { Self {
identifiers: Default::default(), identifiers: Default::default(),
client, validator: client,
config, config,
event_listener: Default::default(), event_listener: Default::default(),
pool: RwLock::new(TxPool::new(ordering)), pool: RwLock::new(TxPool::new(ordering)),
@ -136,9 +136,9 @@ where
self.pool.write().update_base_fee(base_fee); self.pool.write().update_base_fee(base_fee);
} }
/// Get client reference. /// Get the validator reference.
pub fn client(&self) -> &P { pub fn validator(&self) -> &V {
&self.client &self.validator
} }
/// Adds a new transaction listener to the pool that gets notified about every new _ready_ /// Adds a new transaction listener to the pool that gets notified about every new _ready_

View File

@ -39,9 +39,7 @@ pub trait TransactionValidator: Send + Sync {
async fn validate_transaction( async fn validate_transaction(
&self, &self,
_transaction: Self::Transaction, _transaction: Self::Transaction,
) -> TransactionValidationOutcome<Self::Transaction> { ) -> TransactionValidationOutcome<Self::Transaction>;
unimplemented!()
}
} }
/// A valida transaction in the pool. /// A valida transaction in the pool.