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 {
|
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 {
|
||||||
|
|||||||
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user