feat(txpool): replace testing pool with default eth pool (#1857)

This commit is contained in:
Matthias Seitz
2023-03-20 12:53:07 +01:00
committed by GitHub
parent 2a457c7023
commit 8673e95d0a
5 changed files with 58 additions and 28 deletions

View File

@ -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" }

View File

@ -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,

View File

@ -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<Client>
Pool<EthTransactionValidator<Client, PooledTransaction>, CostOrdering<PooledTransaction>>
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<Client, PooledTransaction>,
config: PoolConfig,
) -> Self {
Self::new(validator, CostOrdering::default(), config)
}
}
/// implements the `TransactionPool` interface for various transaction pool API consumers.
#[async_trait::async_trait]
impl<V, T> TransactionPool for Pool<V, T>

View File

@ -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<T>(PhantomData<T>);
@ -39,3 +39,9 @@ where
transaction.cost()
}
}
impl<T> Default for CostOrdering<T> {
fn default() -> Self {
Self(Default::default())
}
}

View File

@ -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<Client> {
pub struct EthTransactionValidator<Client, T> {
/// Spec of the chain
chain_spec: Arc<ChainSpec>,
/// This type fetches account info from the db
@ -99,11 +99,13 @@ pub struct EthTransactionValidator<Client> {
current_max_gas_limit: u64,
/// Current base fee.
base_fee: Option<u128>,
/// Marker for the transaction type
_marker: PhantomData<T>,
}
// === impl EthTransactionValidator ===
impl<Client> EthTransactionValidator<Client> {
impl<Client, Tx> EthTransactionValidator<Client, Tx> {
/// Creates a new instance for the given [ChainSpec]
pub fn new(client: Client, chain_spec: Arc<ChainSpec>) -> Self {
// TODO(mattsse): improve these settings by checking against hardfork
@ -116,6 +118,7 @@ impl<Client> EthTransactionValidator<Client> {
eip1559: true,
current_max_gas_limit: 30_000_000,
base_fee: None,
_marker: Default::default(),
}
}
@ -126,10 +129,12 @@ impl<Client> EthTransactionValidator<Client> {
}
#[async_trait::async_trait]
impl<T: PoolTransaction + AccountProvider + Clone> TransactionValidator
for EthTransactionValidator<T>
impl<Client, Tx> TransactionValidator for EthTransactionValidator<Client, Tx>
where
Client: StateProviderFactory,
Tx: PoolTransaction,
{
type Transaction = T;
type Transaction = Tx;
async fn validate_transaction(
&self,
@ -172,29 +177,26 @@ impl<T: PoolTransaction + AccountProvider + Clone> 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<T: PoolTransaction + AccountProvider + Clone> 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)),
};