mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: use batch tx validation in eth validator (#13490)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
@ -25,7 +25,7 @@ use alloy_eips::{
|
||||
use reth_chainspec::{ChainSpec, EthereumHardforks};
|
||||
use reth_primitives::{InvalidTransactionError, SealedBlock};
|
||||
use reth_primitives_traits::{BlockBody, GotExpected};
|
||||
use reth_storage_api::{AccountReader, StateProviderFactory};
|
||||
use reth_storage_api::{StateProvider, StateProviderFactory};
|
||||
use reth_tasks::TaskSpawner;
|
||||
use std::{
|
||||
marker::PhantomData,
|
||||
@ -80,7 +80,7 @@ where
|
||||
&self,
|
||||
transactions: Vec<(TransactionOrigin, Tx)>,
|
||||
) -> Vec<TransactionValidationOutcome<Tx>> {
|
||||
transactions.into_iter().map(|(origin, tx)| self.validate_one(origin, tx)).collect()
|
||||
self.inner.validate_batch(transactions)
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,11 +175,14 @@ where
|
||||
Client: StateProviderFactory,
|
||||
Tx: EthPoolTransaction,
|
||||
{
|
||||
/// Validates a single transaction.
|
||||
fn validate_one(
|
||||
/// Validates a single transaction using an optional cached state provider.
|
||||
/// If no provider is passed, a new one will be created. This allows reusing
|
||||
/// the same provider across multiple txs.
|
||||
fn validate_one_with_provider(
|
||||
&self,
|
||||
origin: TransactionOrigin,
|
||||
mut transaction: Tx,
|
||||
maybe_state: &mut Option<Box<dyn StateProvider>>,
|
||||
) -> TransactionValidationOutcome<Tx> {
|
||||
// Checks for tx_type
|
||||
match transaction.tx_type() {
|
||||
@ -349,11 +352,22 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
let account = match self
|
||||
.client
|
||||
.latest()
|
||||
.and_then(|state| state.basic_account(transaction.sender()))
|
||||
{
|
||||
// If we don't have a state provider yet, fetch the latest state
|
||||
if maybe_state.is_none() {
|
||||
match self.client.latest() {
|
||||
Ok(new_state) => {
|
||||
*maybe_state = Some(new_state);
|
||||
}
|
||||
Err(err) => {
|
||||
return TransactionValidationOutcome::Error(*transaction.hash(), Box::new(err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let state = maybe_state.as_deref().expect("provider is set");
|
||||
|
||||
// Use provider to get account info
|
||||
let account = match state.basic_account(transaction.sender()) {
|
||||
Ok(account) => account.unwrap_or_default(),
|
||||
Err(err) => {
|
||||
return TransactionValidationOutcome::Error(*transaction.hash(), Box::new(err))
|
||||
@ -368,11 +382,7 @@ where
|
||||
// transactions.
|
||||
if account.has_bytecode() {
|
||||
let is_eip7702 = if self.fork_tracker.is_prague_activated() {
|
||||
match self
|
||||
.client
|
||||
.latest()
|
||||
.and_then(|state| state.bytecode_by_hash(account.get_bytecode_hash()))
|
||||
{
|
||||
match state.bytecode_by_hash(account.get_bytecode_hash()) {
|
||||
Ok(bytecode) => bytecode.unwrap_or_default().is_eip7702(),
|
||||
Err(err) => {
|
||||
return TransactionValidationOutcome::Error(
|
||||
@ -479,6 +489,28 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Validates a single transaction.
|
||||
fn validate_one(
|
||||
&self,
|
||||
origin: TransactionOrigin,
|
||||
transaction: Tx,
|
||||
) -> TransactionValidationOutcome<Tx> {
|
||||
let mut provider = None;
|
||||
self.validate_one_with_provider(origin, transaction, &mut provider)
|
||||
}
|
||||
|
||||
/// Validates all given transactions.
|
||||
fn validate_batch(
|
||||
&self,
|
||||
transactions: Vec<(TransactionOrigin, Tx)>,
|
||||
) -> Vec<TransactionValidationOutcome<Tx>> {
|
||||
let mut provider = None;
|
||||
transactions
|
||||
.into_iter()
|
||||
.map(|(origin, tx)| self.validate_one_with_provider(origin, tx, &mut provider))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn on_new_head_block<T: BlockHeader>(&self, new_tip_block: &T) {
|
||||
// update all forks
|
||||
if self.chain_spec.is_cancun_active_at_timestamp(new_tip_block.timestamp()) {
|
||||
|
||||
Reference in New Issue
Block a user