mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: validate blobs (#4388)
This commit is contained in:
@ -414,6 +414,38 @@ impl Transaction {
|
||||
pub fn is_eip4844(&self) -> bool {
|
||||
matches!(self, Transaction::Eip4844(_))
|
||||
}
|
||||
|
||||
/// Returns the [TxLegacy] variant if the transaction is a legacy transaction.
|
||||
pub fn as_legacy(&self) -> Option<&TxLegacy> {
|
||||
match self {
|
||||
Transaction::Legacy(tx) => Some(tx),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the [TxEip2930] variant if the transaction is an EIP-2930 transaction.
|
||||
pub fn as_eip2830(&self) -> Option<&TxEip2930> {
|
||||
match self {
|
||||
Transaction::Eip2930(tx) => Some(tx),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the [TxEip1559] variant if the transaction is an EIP-1559 transaction.
|
||||
pub fn as_eip1559(&self) -> Option<&TxEip1559> {
|
||||
match self {
|
||||
Transaction::Eip1559(tx) => Some(tx),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the [TxEip4844] variant if the transaction is an EIP-4844 transaction.
|
||||
pub fn as_eip4844(&self) -> Option<&TxEip4844> {
|
||||
match self {
|
||||
Transaction::Eip4844(tx) => Some(tx),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Compact for Transaction {
|
||||
|
||||
@ -5,7 +5,9 @@ use jsonrpsee::{
|
||||
core::Error as RpcError,
|
||||
types::{error::CALL_EXECUTION_FAILED_CODE, ErrorObject},
|
||||
};
|
||||
use reth_primitives::{abi::decode_revert_reason, Address, Bytes, U256};
|
||||
use reth_primitives::{
|
||||
abi::decode_revert_reason, Address, BlobTransactionValidationError, Bytes, U256,
|
||||
};
|
||||
use reth_revm::tracing::js::JsInspectorError;
|
||||
use reth_rpc_types::{error::EthRpcErrorCode, BlockError, CallInputError};
|
||||
use reth_transaction_pool::error::{InvalidPoolTransactionError, PoolError, PoolTransactionError};
|
||||
@ -473,6 +475,9 @@ pub enum RpcPoolError {
|
||||
/// Unable to find the blob for an EIP4844 transaction
|
||||
#[error("blob not found for EIP4844 transaction")]
|
||||
MissingEip4844Blob,
|
||||
/// Thrown if validating the blob sidecar for the transaction failed.
|
||||
#[error(transparent)]
|
||||
InvalidEip4844Blob(BlobTransactionValidationError),
|
||||
#[error(transparent)]
|
||||
Other(Box<dyn std::error::Error + Send + Sync>),
|
||||
}
|
||||
@ -512,6 +517,9 @@ impl From<InvalidPoolTransactionError> for RpcPoolError {
|
||||
InvalidPoolTransactionError::Underpriced => RpcPoolError::Underpriced,
|
||||
InvalidPoolTransactionError::Other(err) => RpcPoolError::PoolTransactionError(err),
|
||||
InvalidPoolTransactionError::MissingEip4844Blob => RpcPoolError::MissingEip4844Blob,
|
||||
InvalidPoolTransactionError::InvalidEip4844Blob(err) => {
|
||||
RpcPoolError::InvalidEip4844Blob(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
//! Transaction pool errors
|
||||
|
||||
use reth_primitives::{Address, InvalidTransactionError, TxHash};
|
||||
use reth_primitives::{Address, BlobTransactionValidationError, InvalidTransactionError, TxHash};
|
||||
|
||||
/// Transaction pool result type.
|
||||
pub type PoolResult<T> = Result<T, PoolError>;
|
||||
@ -141,6 +141,9 @@ pub enum InvalidPoolTransactionError {
|
||||
/// Thrown if we're unable to find the blob for a transaction that was previously extracted
|
||||
#[error("blob not found for EIP4844 transaction")]
|
||||
MissingEip4844Blob,
|
||||
/// Thrown if validating the blob sidecar for the transaction failed.
|
||||
#[error(transparent)]
|
||||
InvalidEip4844Blob(BlobTransactionValidationError),
|
||||
/// Any other error that occurred while inserting/validating that is transaction specific
|
||||
#[error("{0:?}")]
|
||||
Other(Box<dyn PoolTransactionError>),
|
||||
@ -203,6 +206,10 @@ impl InvalidPoolTransactionError {
|
||||
// find the previously extracted blob
|
||||
false
|
||||
}
|
||||
InvalidPoolTransactionError::InvalidEip4844Blob(_) => {
|
||||
// This is only reachable when the blob is invalid
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@ use reth_primitives::{
|
||||
Address, BlobTransactionSidecar, BlobTransactionValidationError,
|
||||
FromRecoveredPooledTransaction, FromRecoveredTransaction, IntoRecoveredTransaction, PeerId,
|
||||
PooledTransactionsElement, PooledTransactionsElementEcRecovered, SealedBlock, Transaction,
|
||||
TransactionKind, TransactionSignedEcRecovered, TxHash, EIP1559_TX_TYPE_ID, EIP4844_TX_TYPE_ID,
|
||||
H256, U256,
|
||||
TransactionKind, TransactionSignedEcRecovered, TxEip4844, TxHash, EIP1559_TX_TYPE_ID,
|
||||
EIP4844_TX_TYPE_ID, H256, U256,
|
||||
};
|
||||
use reth_rlp::Encodable;
|
||||
use std::{
|
||||
@ -656,6 +656,9 @@ pub trait EthPoolTransaction: PoolTransaction {
|
||||
/// Extracts the blob sidecar from the transaction.
|
||||
fn take_blob(&mut self) -> EthBlobTransactionSidecar;
|
||||
|
||||
/// Returns the transaction as EIP-4844 transaction if it is one.
|
||||
fn as_eip4844(&self) -> Option<&TxEip4844>;
|
||||
|
||||
/// Validates the blob sidecar of the transaction with the given settings.
|
||||
fn validate_blob(
|
||||
&self,
|
||||
@ -845,6 +848,10 @@ impl EthPoolTransaction for EthPooledTransaction {
|
||||
}
|
||||
}
|
||||
|
||||
fn as_eip4844(&self) -> Option<&TxEip4844> {
|
||||
self.transaction.as_eip4844()
|
||||
}
|
||||
|
||||
fn validate_blob(
|
||||
&self,
|
||||
sidecar: &BlobTransactionSidecar,
|
||||
|
||||
@ -74,7 +74,6 @@ pub(crate) struct EthTransactionValidatorInner<Client, T> {
|
||||
/// Toggle to determine if a local transaction should be propagated
|
||||
propagate_local_transactions: bool,
|
||||
/// Stores the setup and parameters needed for validating KZG proofs.
|
||||
#[allow(unused)]
|
||||
kzg_settings: Arc<KzgSettings>,
|
||||
/// Marker for the transaction type
|
||||
_marker: PhantomData<T>,
|
||||
@ -198,7 +197,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
let mut blob_sidecar = None;
|
||||
let mut maybe_blob_sidecar = None;
|
||||
|
||||
// blob tx checks
|
||||
if transaction.is_eip4844() {
|
||||
@ -230,8 +229,23 @@ where
|
||||
}
|
||||
}
|
||||
EthBlobTransactionSidecar::Present(blob) => {
|
||||
//TODO(mattsse): verify the blob
|
||||
blob_sidecar = Some(blob);
|
||||
if let Some(eip4844) = transaction.as_eip4844() {
|
||||
// validate the blob
|
||||
if let Err(err) = eip4844.validate_blob(&blob, &self.kzg_settings) {
|
||||
return TransactionValidationOutcome::Invalid(
|
||||
transaction,
|
||||
InvalidPoolTransactionError::InvalidEip4844Blob(err),
|
||||
)
|
||||
}
|
||||
// store the extracted blob
|
||||
maybe_blob_sidecar = Some(blob);
|
||||
} else {
|
||||
// this should not happen
|
||||
return TransactionValidationOutcome::Invalid(
|
||||
transaction,
|
||||
InvalidTransactionError::TxTypeNotSupported.into(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -281,7 +295,7 @@ where
|
||||
TransactionValidationOutcome::Valid {
|
||||
balance: account.balance,
|
||||
state_nonce: account.nonce,
|
||||
transaction: ValidTransaction::new(transaction, blob_sidecar),
|
||||
transaction: ValidTransaction::new(transaction, maybe_blob_sidecar),
|
||||
// by this point assume all external transactions should be propagated
|
||||
propagate: match origin {
|
||||
TransactionOrigin::External => true,
|
||||
|
||||
Reference in New Issue
Block a user