mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: add blob sidecar extraction to tx validation (#4254)
This commit is contained in:
@ -4,11 +4,11 @@
|
||||
//! to be generic over it.
|
||||
|
||||
use crate::{
|
||||
error::PoolError, traits::PendingTransactionListenerKind, AllPoolTransactions,
|
||||
AllTransactionsEvents, BestTransactions, BlockInfo, EthPooledTransaction, NewTransactionEvent,
|
||||
PoolResult, PoolSize, PoolTransaction, PropagatedTransactions, TransactionEvents,
|
||||
TransactionOrigin, TransactionPool, TransactionValidationOutcome, TransactionValidator,
|
||||
ValidPoolTransaction,
|
||||
error::PoolError, traits::PendingTransactionListenerKind, validate::ValidTransaction,
|
||||
AllPoolTransactions, AllTransactionsEvents, BestTransactions, BlockInfo, EthPooledTransaction,
|
||||
NewTransactionEvent, PoolResult, PoolSize, PoolTransaction, PropagatedTransactions,
|
||||
TransactionEvents, TransactionOrigin, TransactionPool, TransactionValidationOutcome,
|
||||
TransactionValidator, ValidPoolTransaction,
|
||||
};
|
||||
use reth_primitives::{Address, TxHash};
|
||||
use std::{collections::HashSet, marker::PhantomData, sync::Arc};
|
||||
@ -184,7 +184,7 @@ impl<T: PoolTransaction> TransactionValidator for MockTransactionValidator<T> {
|
||||
TransactionValidationOutcome::Valid {
|
||||
balance: Default::default(),
|
||||
state_nonce: 0,
|
||||
transaction,
|
||||
transaction: ValidTransaction::Valid(transaction),
|
||||
propagate: match origin {
|
||||
TransactionOrigin::External => true,
|
||||
TransactionOrigin::Local => self.propagate_local,
|
||||
|
||||
@ -96,7 +96,9 @@ mod events;
|
||||
pub use events::{FullTransactionEvent, TransactionEvent};
|
||||
|
||||
mod listener;
|
||||
use crate::{pool::txpool::UpdateOutcome, traits::PendingTransactionListenerKind};
|
||||
use crate::{
|
||||
pool::txpool::UpdateOutcome, traits::PendingTransactionListenerKind, validate::ValidTransaction,
|
||||
};
|
||||
pub use listener::{AllTransactionsEvents, TransactionEvents};
|
||||
|
||||
mod best;
|
||||
@ -314,6 +316,17 @@ where
|
||||
let transaction_id = TransactionId::new(sender_id, transaction.nonce());
|
||||
let encoded_length = transaction.encoded_length();
|
||||
|
||||
let (transaction, _maybe_sidecar) = match transaction {
|
||||
ValidTransaction::Valid(tx) => (tx, None),
|
||||
ValidTransaction::ValidWithSidecar { transaction, sidecar } => {
|
||||
debug_assert!(
|
||||
transaction.is_eip4844(),
|
||||
"validator returned sidecar for non EIP-4844 transaction"
|
||||
);
|
||||
(transaction, Some(sidecar))
|
||||
}
|
||||
};
|
||||
|
||||
let tx = ValidPoolTransaction {
|
||||
transaction,
|
||||
transaction_id,
|
||||
|
||||
@ -4,8 +4,8 @@ use crate::{
|
||||
error::InvalidPoolTransactionError,
|
||||
traits::{PoolTransaction, TransactionOrigin},
|
||||
validate::{
|
||||
task::ValidationJobSender, TransactionValidatorError, ValidationTask, MAX_INIT_CODE_SIZE,
|
||||
TX_MAX_SIZE,
|
||||
task::ValidationJobSender, TransactionValidatorError, ValidTransaction, ValidationTask,
|
||||
MAX_INIT_CODE_SIZE, TX_MAX_SIZE,
|
||||
},
|
||||
TransactionValidationOutcome, TransactionValidator,
|
||||
};
|
||||
@ -499,7 +499,7 @@ where
|
||||
TransactionValidationOutcome::Valid {
|
||||
balance: account.balance,
|
||||
state_nonce: account.nonce,
|
||||
transaction,
|
||||
transaction: ValidTransaction::Valid(transaction),
|
||||
// by this point assume all external transactions should be propagated
|
||||
propagate: match origin {
|
||||
TransactionOrigin::External => true,
|
||||
|
||||
@ -6,7 +6,8 @@ use crate::{
|
||||
traits::{PoolTransaction, TransactionOrigin},
|
||||
};
|
||||
use reth_primitives::{
|
||||
Address, IntoRecoveredTransaction, TransactionKind, TransactionSignedEcRecovered, TxHash, U256,
|
||||
Address, BlobTransactionSidecar, IntoRecoveredTransaction, TransactionKind,
|
||||
TransactionSignedEcRecovered, TxHash, H256, U256,
|
||||
};
|
||||
use std::{fmt, time::Instant};
|
||||
|
||||
@ -32,9 +33,13 @@ pub enum TransactionValidationOutcome<T: PoolTransaction> {
|
||||
balance: U256,
|
||||
/// Current nonce of the sender.
|
||||
state_nonce: u64,
|
||||
/// Validated transaction.
|
||||
// TODO add enum type for blob,regular?
|
||||
transaction: T,
|
||||
/// The validated transaction.
|
||||
///
|
||||
/// See also [ValidTransaction].
|
||||
///
|
||||
/// If this is a _new_ EIP-4844 blob transaction, then this must contain the extracted
|
||||
/// sidecar.
|
||||
transaction: ValidTransaction<T>,
|
||||
/// Whether to propagate the transaction to the network.
|
||||
propagate: bool,
|
||||
},
|
||||
@ -56,6 +61,65 @@ impl<T: PoolTransaction> TransactionValidationOutcome<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper type for a transaction that is valid and has an optional extracted EIP-4844 blob
|
||||
/// transaction sidecar.
|
||||
///
|
||||
/// If this is provided, then the sidecar will be temporarily stored in the blob store until the
|
||||
/// transaction is finalized.
|
||||
///
|
||||
/// Note: Since blob transactions can be re-injected without their sidecar (after reorg), the
|
||||
/// validator can omit the sidecar if it is still in the blob store and return a
|
||||
/// [ValidTransaction::Valid] instead.
|
||||
#[derive(Debug)]
|
||||
pub enum ValidTransaction<T> {
|
||||
/// A valid transaction without a sidecar.
|
||||
Valid(T),
|
||||
/// A valid transaction for which a sidecar should be stored.
|
||||
///
|
||||
/// Caution: The [TransactionValidator] must ensure that this is only returned for EIP-4844
|
||||
/// transactions.
|
||||
ValidWithSidecar {
|
||||
/// The valid EIP-4844 transaction.
|
||||
transaction: T,
|
||||
/// The extracted sidecar of that transaction
|
||||
sidecar: BlobTransactionSidecar,
|
||||
},
|
||||
}
|
||||
|
||||
impl<T: PoolTransaction> ValidTransaction<T> {
|
||||
#[inline]
|
||||
pub(crate) fn transaction(&self) -> &T {
|
||||
match self {
|
||||
Self::Valid(transaction) => transaction,
|
||||
Self::ValidWithSidecar { transaction, .. } => transaction,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the address of that transaction.
|
||||
#[inline]
|
||||
pub(crate) fn sender(&self) -> Address {
|
||||
self.transaction().sender()
|
||||
}
|
||||
|
||||
/// Returns the hash of the transaction.
|
||||
#[inline]
|
||||
pub(crate) fn hash(&self) -> &H256 {
|
||||
self.transaction().hash()
|
||||
}
|
||||
|
||||
/// Returns the length of the rlp encoded object
|
||||
#[inline]
|
||||
pub(crate) fn encoded_length(&self) -> usize {
|
||||
self.transaction().encoded_length()
|
||||
}
|
||||
|
||||
/// Returns the nonce of the transaction.
|
||||
#[inline]
|
||||
pub(crate) fn nonce(&self) -> u64 {
|
||||
self.transaction().nonce()
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides support for validating transaction at any given state of the chain
|
||||
#[async_trait::async_trait]
|
||||
pub trait TransactionValidator: Send + Sync {
|
||||
@ -113,6 +177,11 @@ pub trait TransactionValidator: Send + Sync {
|
||||
}
|
||||
|
||||
/// A valid transaction in the pool.
|
||||
///
|
||||
/// This is used as the internal representation of a transaction inside the pool.
|
||||
///
|
||||
/// For EIP-4844 blob transactions this will _not_ contain the blob sidecar which is stored
|
||||
/// separately in the [BlobStore](crate::blobstore::BlobStore).
|
||||
pub struct ValidPoolTransaction<T: PoolTransaction> {
|
||||
/// The transaction
|
||||
pub transaction: T,
|
||||
|
||||
@ -10,8 +10,8 @@
|
||||
use reth_network::{config::rng_secret_key, NetworkConfig, NetworkManager};
|
||||
use reth_provider::test_utils::NoopProvider;
|
||||
use reth_transaction_pool::{
|
||||
CoinbaseTipOrdering, EthPooledTransaction, PoolTransaction, TransactionOrigin, TransactionPool,
|
||||
TransactionValidationOutcome, TransactionValidator,
|
||||
validate::ValidTransaction, CoinbaseTipOrdering, EthPooledTransaction, PoolTransaction,
|
||||
TransactionOrigin, TransactionPool, TransactionValidationOutcome, TransactionValidator,
|
||||
};
|
||||
|
||||
#[tokio::main]
|
||||
@ -79,7 +79,7 @@ impl TransactionValidator for OkValidator {
|
||||
TransactionValidationOutcome::Valid {
|
||||
balance: transaction.cost(),
|
||||
state_nonce: transaction.nonce(),
|
||||
transaction,
|
||||
transaction: ValidTransaction::Valid(transaction),
|
||||
propagate: false,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user