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 {
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 {

View File

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

View File

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

View File

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

View File

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