From 8673e95d0aa44083be627e337df06e5c641c4f67 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 20 Mar 2023 12:53:07 +0100 Subject: [PATCH] feat(txpool): replace testing pool with default eth pool (#1857) --- bin/reth/Cargo.toml | 2 +- bin/reth/src/node/mod.rs | 12 ++++--- crates/transaction-pool/src/lib.rs | 20 +++++++++-- crates/transaction-pool/src/ordering.rs | 8 ++++- crates/transaction-pool/src/validate.rs | 44 ++++++++++++++----------- 5 files changed, 58 insertions(+), 28 deletions(-) diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml index f1952517c5..dc548fd25a 100644 --- a/bin/reth/Cargo.toml +++ b/bin/reth/Cargo.toml @@ -16,7 +16,7 @@ reth-revm-inspectors = { path = "../../crates/revm/revm-inspectors" } reth-staged-sync = { path = "../../crates/staged-sync" } reth-stages = { path = "../../crates/stages"} reth-interfaces = { path = "../../crates/interfaces", features = ["test-utils"] } -reth-transaction-pool = { path = "../../crates/transaction-pool", features = ["test-utils"] } +reth-transaction-pool = { path = "../../crates/transaction-pool" } reth-beacon-consensus = { path = "../../crates/consensus/beacon" } reth-executor = { path = "../../crates/executor" } reth-rpc-engine-api = { path = "../../crates/rpc/rpc-engine-api" } diff --git a/bin/reth/src/node/mod.rs b/bin/reth/src/node/mod.rs index bb3641f2ab..bf59545497 100644 --- a/bin/reth/src/node/mod.rs +++ b/bin/reth/src/node/mod.rs @@ -54,6 +54,7 @@ use reth_stages::{ stages::{ExecutionStage, HeaderSyncMode, SenderRecoveryStage, TotalDifficultyStage, FINISH}, }; use reth_tasks::TaskExecutor; +use reth_transaction_pool::EthTransactionValidator; use std::{ net::{Ipv4Addr, SocketAddr, SocketAddrV4}, path::PathBuf, @@ -173,7 +174,7 @@ impl Command { info!(target: "reth::cli", path = %self.db, "Opening database"); let db = Arc::new(init_db(&self.db)?); - let shareable_db = ShareableDatabase::new(Arc::clone(&db), self.chain.clone()); + let shareable_db = ShareableDatabase::new(Arc::clone(&db), Arc::clone(&self.chain)); info!(target: "reth::cli", "Database opened"); self.start_metrics_endpoint()?; @@ -193,14 +194,17 @@ impl Command { let network = self.start_network(network_config, &ctx.task_executor, ()).await?; info!(target: "reth::cli", peer_id = %network.peer_id(), local_addr = %network.local_addr(), "Connected to P2P network"); - let test_transaction_pool = reth_transaction_pool::test_utils::testing_pool(); + let transaction_pool = reth_transaction_pool::Pool::eth_pool( + EthTransactionValidator::new(shareable_db.clone(), Arc::clone(&self.chain)), + Default::default(), + ); info!(target: "reth::cli", "Test transaction pool initialized"); let _rpc_server = self .rpc .start_rpc_server( shareable_db.clone(), - test_transaction_pool.clone(), + transaction_pool.clone(), network.clone(), ctx.task_executor.clone(), ) @@ -220,7 +224,7 @@ impl Command { .rpc .start_auth_server( shareable_db, - test_transaction_pool, + transaction_pool, network.clone(), ctx.task_executor.clone(), engine_api_handle, diff --git a/crates/transaction-pool/src/lib.rs b/crates/transaction-pool/src/lib.rs index cd006c14c6..1d2a605e08 100644 --- a/crates/transaction-pool/src/lib.rs +++ b/crates/transaction-pool/src/lib.rs @@ -92,13 +92,12 @@ pub use crate::{ }, }; use crate::{ - error::PoolResult, + error::{PoolError, PoolResult}, pool::PoolInner, traits::{NewTransactionEvent, PoolSize}, }; - -use crate::error::PoolError; use reth_primitives::{TxHash, U256}; +use reth_provider::StateProviderFactory; use std::{collections::HashMap, sync::Arc}; use tokio::sync::mpsc::Receiver; @@ -205,6 +204,21 @@ where } } +impl + Pool, CostOrdering> +where + Client: StateProviderFactory, +{ + /// Returns a new [Pool] that uses the default [EthTransactionValidator] when validating + /// [PooledTransaction]s and ords via [CostOrdering] + pub fn eth_pool( + validator: EthTransactionValidator, + config: PoolConfig, + ) -> Self { + Self::new(validator, CostOrdering::default(), config) + } +} + /// implements the `TransactionPool` interface for various transaction pool API consumers. #[async_trait::async_trait] impl TransactionPool for Pool diff --git a/crates/transaction-pool/src/ordering.rs b/crates/transaction-pool/src/ordering.rs index b96db09548..21334771a9 100644 --- a/crates/transaction-pool/src/ordering.rs +++ b/crates/transaction-pool/src/ordering.rs @@ -24,7 +24,7 @@ pub trait TransactionOrdering: Send + Sync + 'static { /// /// The transactions are ordered by their cost. The higher the cost, /// the higher the priority of this transaction is. -#[derive(Debug, Default)] +#[derive(Debug)] #[non_exhaustive] pub struct CostOrdering(PhantomData); @@ -39,3 +39,9 @@ where transaction.cost() } } + +impl Default for CostOrdering { + fn default() -> Self { + Self(Default::default()) + } +} diff --git a/crates/transaction-pool/src/validate.rs b/crates/transaction-pool/src/validate.rs index 37c1829be6..581a588a8f 100644 --- a/crates/transaction-pool/src/validate.rs +++ b/crates/transaction-pool/src/validate.rs @@ -11,8 +11,8 @@ use reth_primitives::{ TransactionSignedEcRecovered, TxHash, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID, LEGACY_TX_TYPE_ID, U256, }; -use reth_provider::AccountProvider; -use std::{fmt, sync::Arc, time::Instant}; +use reth_provider::{AccountProvider, StateProviderFactory}; +use std::{fmt, marker::PhantomData, sync::Arc, time::Instant}; /// A Result type returned after checking a transaction's validity. #[derive(Debug)] @@ -67,7 +67,7 @@ pub trait TransactionValidator: Send + Sync { /// `max_init_code_size` should be configurable so this will take it as an argument. fn ensure_max_init_code_size( &self, - transaction: Self::Transaction, + transaction: &Self::Transaction, max_init_code_size: usize, ) -> Result<(), InvalidPoolTransactionError> { if *transaction.kind() == TransactionKind::Create && transaction.size() > max_init_code_size @@ -84,7 +84,7 @@ pub trait TransactionValidator: Send + Sync { /// A [TransactionValidator] implementation that validates ethereum transaction. #[derive(Debug, Clone)] -pub struct EthTransactionValidator { +pub struct EthTransactionValidator { /// Spec of the chain chain_spec: Arc, /// This type fetches account info from the db @@ -99,11 +99,13 @@ pub struct EthTransactionValidator { current_max_gas_limit: u64, /// Current base fee. base_fee: Option, + /// Marker for the transaction type + _marker: PhantomData, } // === impl EthTransactionValidator === -impl EthTransactionValidator { +impl EthTransactionValidator { /// Creates a new instance for the given [ChainSpec] pub fn new(client: Client, chain_spec: Arc) -> Self { // TODO(mattsse): improve these settings by checking against hardfork @@ -116,6 +118,7 @@ impl EthTransactionValidator { eip1559: true, current_max_gas_limit: 30_000_000, base_fee: None, + _marker: Default::default(), } } @@ -126,10 +129,12 @@ impl EthTransactionValidator { } #[async_trait::async_trait] -impl TransactionValidator - for EthTransactionValidator +impl TransactionValidator for EthTransactionValidator +where + Client: StateProviderFactory, + Tx: PoolTransaction, { - type Transaction = T; + type Transaction = Tx; async fn validate_transaction( &self, @@ -172,29 +177,26 @@ impl TransactionValidator // Reject transactions over defined size to prevent DOS attacks if transaction.size() > TX_MAX_SIZE { + let size = transaction.size(); return TransactionValidationOutcome::Invalid( - transaction.clone(), - InvalidPoolTransactionError::OversizedData(transaction.size(), TX_MAX_SIZE), + transaction, + InvalidPoolTransactionError::OversizedData(size, TX_MAX_SIZE), ) } // Check whether the init code size has been exceeded. if self.shanghai { - if let Err(err) = - self.ensure_max_init_code_size(transaction.clone(), MAX_INIT_CODE_SIZE) - { + if let Err(err) = self.ensure_max_init_code_size(&transaction, MAX_INIT_CODE_SIZE) { return TransactionValidationOutcome::Invalid(transaction, err) } } // Checks for gas limit if transaction.gas_limit() > self.current_max_gas_limit { + let gas_limit = transaction.gas_limit(); return TransactionValidationOutcome::Invalid( - transaction.clone(), - InvalidPoolTransactionError::ExceedsGasLimit( - transaction.gas_limit(), - self.current_max_gas_limit, - ), + transaction, + InvalidPoolTransactionError::ExceedsGasLimit(gas_limit, self.current_max_gas_limit), ) } @@ -222,7 +224,11 @@ impl TransactionValidator ) } - let account = match self.client.basic_account(transaction.sender()) { + let account = match self + .client + .latest() + .and_then(|state| state.basic_account(transaction.sender())) + { Ok(account) => account, Err(err) => return TransactionValidationOutcome::Error(transaction, Box::new(err)), };