feat: validate blobs (#4388)

This commit is contained in:
Matthias Seitz
2023-08-29 09:25:34 -07:00
committed by GitHub
parent 03afe376b8
commit 2fc574f329
5 changed files with 77 additions and 9 deletions

View File

@ -414,6 +414,38 @@ impl Transaction {
pub fn is_eip4844(&self) -> bool { pub fn is_eip4844(&self) -> bool {
matches!(self, Transaction::Eip4844(_)) 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 { impl Compact for Transaction {

View File

@ -5,7 +5,9 @@ use jsonrpsee::{
core::Error as RpcError, core::Error as RpcError,
types::{error::CALL_EXECUTION_FAILED_CODE, ErrorObject}, 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_revm::tracing::js::JsInspectorError;
use reth_rpc_types::{error::EthRpcErrorCode, BlockError, CallInputError}; use reth_rpc_types::{error::EthRpcErrorCode, BlockError, CallInputError};
use reth_transaction_pool::error::{InvalidPoolTransactionError, PoolError, PoolTransactionError}; use reth_transaction_pool::error::{InvalidPoolTransactionError, PoolError, PoolTransactionError};
@ -473,6 +475,9 @@ pub enum RpcPoolError {
/// Unable to find the blob for an EIP4844 transaction /// Unable to find the blob for an EIP4844 transaction
#[error("blob not found for EIP4844 transaction")] #[error("blob not found for EIP4844 transaction")]
MissingEip4844Blob, MissingEip4844Blob,
/// Thrown if validating the blob sidecar for the transaction failed.
#[error(transparent)]
InvalidEip4844Blob(BlobTransactionValidationError),
#[error(transparent)] #[error(transparent)]
Other(Box<dyn std::error::Error + Send + Sync>), Other(Box<dyn std::error::Error + Send + Sync>),
} }
@ -512,6 +517,9 @@ impl From<InvalidPoolTransactionError> for RpcPoolError {
InvalidPoolTransactionError::Underpriced => RpcPoolError::Underpriced, InvalidPoolTransactionError::Underpriced => RpcPoolError::Underpriced,
InvalidPoolTransactionError::Other(err) => RpcPoolError::PoolTransactionError(err), InvalidPoolTransactionError::Other(err) => RpcPoolError::PoolTransactionError(err),
InvalidPoolTransactionError::MissingEip4844Blob => RpcPoolError::MissingEip4844Blob, InvalidPoolTransactionError::MissingEip4844Blob => RpcPoolError::MissingEip4844Blob,
InvalidPoolTransactionError::InvalidEip4844Blob(err) => {
RpcPoolError::InvalidEip4844Blob(err)
}
} }
} }
} }

View File

@ -1,6 +1,6 @@
//! Transaction pool errors //! Transaction pool errors
use reth_primitives::{Address, InvalidTransactionError, TxHash}; use reth_primitives::{Address, BlobTransactionValidationError, InvalidTransactionError, TxHash};
/// Transaction pool result type. /// Transaction pool result type.
pub type PoolResult<T> = Result<T, PoolError>; 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 /// Thrown if we're unable to find the blob for a transaction that was previously extracted
#[error("blob not found for EIP4844 transaction")] #[error("blob not found for EIP4844 transaction")]
MissingEip4844Blob, 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 /// Any other error that occurred while inserting/validating that is transaction specific
#[error("{0:?}")] #[error("{0:?}")]
Other(Box<dyn PoolTransactionError>), Other(Box<dyn PoolTransactionError>),
@ -203,6 +206,10 @@ impl InvalidPoolTransactionError {
// find the previously extracted blob // find the previously extracted blob
false false
} }
InvalidPoolTransactionError::InvalidEip4844Blob(_) => {
// This is only reachable when the blob is invalid
true
}
} }
} }
} }

View File

@ -9,8 +9,8 @@ use reth_primitives::{
Address, BlobTransactionSidecar, BlobTransactionValidationError, Address, BlobTransactionSidecar, BlobTransactionValidationError,
FromRecoveredPooledTransaction, FromRecoveredTransaction, IntoRecoveredTransaction, PeerId, FromRecoveredPooledTransaction, FromRecoveredTransaction, IntoRecoveredTransaction, PeerId,
PooledTransactionsElement, PooledTransactionsElementEcRecovered, SealedBlock, Transaction, PooledTransactionsElement, PooledTransactionsElementEcRecovered, SealedBlock, Transaction,
TransactionKind, TransactionSignedEcRecovered, TxHash, EIP1559_TX_TYPE_ID, EIP4844_TX_TYPE_ID, TransactionKind, TransactionSignedEcRecovered, TxEip4844, TxHash, EIP1559_TX_TYPE_ID,
H256, U256, EIP4844_TX_TYPE_ID, H256, U256,
}; };
use reth_rlp::Encodable; use reth_rlp::Encodable;
use std::{ use std::{
@ -656,6 +656,9 @@ pub trait EthPoolTransaction: PoolTransaction {
/// Extracts the blob sidecar from the transaction. /// Extracts the blob sidecar from the transaction.
fn take_blob(&mut self) -> EthBlobTransactionSidecar; 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. /// Validates the blob sidecar of the transaction with the given settings.
fn validate_blob( fn validate_blob(
&self, &self,
@ -845,6 +848,10 @@ impl EthPoolTransaction for EthPooledTransaction {
} }
} }
fn as_eip4844(&self) -> Option<&TxEip4844> {
self.transaction.as_eip4844()
}
fn validate_blob( fn validate_blob(
&self, &self,
sidecar: &BlobTransactionSidecar, sidecar: &BlobTransactionSidecar,

View File

@ -74,7 +74,6 @@ pub(crate) struct EthTransactionValidatorInner<Client, T> {
/// Toggle to determine if a local transaction should be propagated /// Toggle to determine if a local transaction should be propagated
propagate_local_transactions: bool, propagate_local_transactions: bool,
/// Stores the setup and parameters needed for validating KZG proofs. /// Stores the setup and parameters needed for validating KZG proofs.
#[allow(unused)]
kzg_settings: Arc<KzgSettings>, kzg_settings: Arc<KzgSettings>,
/// Marker for the transaction type /// Marker for the transaction type
_marker: PhantomData<T>, _marker: PhantomData<T>,
@ -198,7 +197,7 @@ where
} }
} }
let mut blob_sidecar = None; let mut maybe_blob_sidecar = None;
// blob tx checks // blob tx checks
if transaction.is_eip4844() { if transaction.is_eip4844() {
@ -230,8 +229,23 @@ where
} }
} }
EthBlobTransactionSidecar::Present(blob) => { EthBlobTransactionSidecar::Present(blob) => {
//TODO(mattsse): verify the blob if let Some(eip4844) = transaction.as_eip4844() {
blob_sidecar = Some(blob); // 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 { TransactionValidationOutcome::Valid {
balance: account.balance, balance: account.balance,
state_nonce: account.nonce, 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 // by this point assume all external transactions should be propagated
propagate: match origin { propagate: match origin {
TransactionOrigin::External => true, TransactionOrigin::External => true,