mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 19:09:54 +00:00
feat: add blob count checks (#4447)
Co-authored-by: Dan Cline <6798349+Rjected@users.noreply.github.com>
This commit is contained in:
@ -20,7 +20,7 @@ pub const MAX_DATA_GAS_PER_BLOCK: u64 = 786_432u64; // 0xC0000
|
|||||||
pub const TARGET_DATA_GAS_PER_BLOCK: u64 = 393_216u64; // 0x60000
|
pub const TARGET_DATA_GAS_PER_BLOCK: u64 = 393_216u64; // 0x60000
|
||||||
|
|
||||||
/// Maximum number of data blobs in a single block.
|
/// Maximum number of data blobs in a single block.
|
||||||
pub const MAX_BLOBS_PER_BLOCK: u64 = MAX_DATA_GAS_PER_BLOCK / DATA_GAS_PER_BLOB; // 786432 / 131072 = 6
|
pub const MAX_BLOBS_PER_BLOCK: usize = (MAX_DATA_GAS_PER_BLOCK / DATA_GAS_PER_BLOB) as usize; // 786432 / 131072 = 6
|
||||||
|
|
||||||
/// Target number of data blobs in a single block.
|
/// Target number of data blobs in a single block.
|
||||||
pub const TARGET_BLOBS_PER_BLOCK: u64 = TARGET_DATA_GAS_PER_BLOCK / DATA_GAS_PER_BLOB; // 393216 / 131072 = 3
|
pub const TARGET_BLOBS_PER_BLOCK: u64 = TARGET_DATA_GAS_PER_BLOCK / DATA_GAS_PER_BLOB; // 393216 / 131072 = 3
|
||||||
|
|||||||
@ -473,8 +473,19 @@ pub enum RpcPoolError {
|
|||||||
#[error("{0:?}")]
|
#[error("{0:?}")]
|
||||||
PoolTransactionError(Box<dyn PoolTransactionError>),
|
PoolTransactionError(Box<dyn PoolTransactionError>),
|
||||||
/// 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 sidecar not found for EIP4844 transaction")]
|
||||||
MissingEip4844Blob,
|
MissingEip4844Blob,
|
||||||
|
/// Thrown if an EIP-4844 without any blobs arrives
|
||||||
|
#[error("blobless blob transaction")]
|
||||||
|
NoEip4844Blobs,
|
||||||
|
/// Thrown if an EIP-4844 without any blobs arrives
|
||||||
|
#[error("too many blobs in transaction: have {have}, permitted {permitted}")]
|
||||||
|
TooManyEip4844Blobs {
|
||||||
|
/// Number of blobs the transaction has
|
||||||
|
have: usize,
|
||||||
|
/// Number of maximum blobs the transaction can have
|
||||||
|
permitted: usize,
|
||||||
|
},
|
||||||
/// Thrown if validating the blob sidecar for the transaction failed.
|
/// Thrown if validating the blob sidecar for the transaction failed.
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
InvalidEip4844Blob(BlobTransactionValidationError),
|
InvalidEip4844Blob(BlobTransactionValidationError),
|
||||||
@ -516,7 +527,13 @@ impl From<InvalidPoolTransactionError> for RpcPoolError {
|
|||||||
InvalidPoolTransactionError::OversizedData(_, _) => RpcPoolError::OversizedData,
|
InvalidPoolTransactionError::OversizedData(_, _) => RpcPoolError::OversizedData,
|
||||||
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::MissingEip4844BlobSidecar => {
|
||||||
|
RpcPoolError::MissingEip4844Blob
|
||||||
|
}
|
||||||
|
InvalidPoolTransactionError::NoEip4844Blobs => RpcPoolError::NoEip4844Blobs,
|
||||||
|
InvalidPoolTransactionError::TooManyEip4844Blobs { have, permitted } => {
|
||||||
|
RpcPoolError::TooManyEip4844Blobs { have, permitted }
|
||||||
|
}
|
||||||
InvalidPoolTransactionError::InvalidEip4844Blob(err) => {
|
InvalidPoolTransactionError::InvalidEip4844Blob(err) => {
|
||||||
RpcPoolError::InvalidEip4844Blob(err)
|
RpcPoolError::InvalidEip4844Blob(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -139,8 +139,19 @@ pub enum InvalidPoolTransactionError {
|
|||||||
#[error("transaction underpriced")]
|
#[error("transaction underpriced")]
|
||||||
Underpriced,
|
Underpriced,
|
||||||
/// 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 sidecar not found for EIP4844 transaction")]
|
||||||
MissingEip4844Blob,
|
MissingEip4844BlobSidecar,
|
||||||
|
/// Thrown if an EIP-4844 without any blobs arrives
|
||||||
|
#[error("blobless blob transaction")]
|
||||||
|
NoEip4844Blobs,
|
||||||
|
/// Thrown if an EIP-4844 without any blobs arrives
|
||||||
|
#[error("too many blobs in transaction: have {have}, permitted {permitted}")]
|
||||||
|
TooManyEip4844Blobs {
|
||||||
|
/// Number of blobs the transaction has
|
||||||
|
have: usize,
|
||||||
|
/// Number of maximum blobs the transaction can have
|
||||||
|
permitted: usize,
|
||||||
|
},
|
||||||
/// Thrown if validating the blob sidecar for the transaction failed.
|
/// Thrown if validating the blob sidecar for the transaction failed.
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
InvalidEip4844Blob(BlobTransactionValidationError),
|
InvalidEip4844Blob(BlobTransactionValidationError),
|
||||||
@ -209,7 +220,7 @@ impl InvalidPoolTransactionError {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
InvalidPoolTransactionError::Other(err) => err.is_bad_transaction(),
|
InvalidPoolTransactionError::Other(err) => err.is_bad_transaction(),
|
||||||
InvalidPoolTransactionError::MissingEip4844Blob => {
|
InvalidPoolTransactionError::MissingEip4844BlobSidecar => {
|
||||||
// this is only reachable when blob transactions are reinjected and we're unable to
|
// this is only reachable when blob transactions are reinjected and we're unable to
|
||||||
// find the previously extracted blob
|
// find the previously extracted blob
|
||||||
false
|
false
|
||||||
@ -223,6 +234,14 @@ impl InvalidPoolTransactionError {
|
|||||||
// thrown for valid(good) blob transactions
|
// thrown for valid(good) blob transactions
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
InvalidPoolTransactionError::NoEip4844Blobs => {
|
||||||
|
// this is a malformed transaction and should not be sent over the network
|
||||||
|
true
|
||||||
|
}
|
||||||
|
InvalidPoolTransactionError::TooManyEip4844Blobs { .. } => {
|
||||||
|
// this is a malformed transaction and should not be sent over the network
|
||||||
|
true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -666,6 +666,11 @@ 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 number of blobs this transaction has.
|
||||||
|
fn blob_count(&self) -> usize {
|
||||||
|
self.as_eip4844().map(|tx| tx.blob_versioned_hashes.len()).unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns the transaction as EIP-4844 transaction if it is one.
|
/// Returns the transaction as EIP-4844 transaction if it is one.
|
||||||
fn as_eip4844(&self) -> Option<&TxEip4844>;
|
fn as_eip4844(&self) -> Option<&TxEip4844>;
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,10 @@ use crate::{
|
|||||||
TransactionValidationTaskExecutor, TransactionValidator,
|
TransactionValidationTaskExecutor, TransactionValidator,
|
||||||
};
|
};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
constants::{eip4844::MAINNET_KZG_TRUSTED_SETUP, ETHEREUM_BLOCK_GAS_LIMIT},
|
constants::{
|
||||||
|
eip4844::{MAINNET_KZG_TRUSTED_SETUP, MAX_BLOBS_PER_BLOCK},
|
||||||
|
ETHEREUM_BLOCK_GAS_LIMIT,
|
||||||
|
},
|
||||||
kzg::KzgSettings,
|
kzg::KzgSettings,
|
||||||
ChainSpec, InvalidTransactionError, SealedBlock, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID,
|
ChainSpec, InvalidTransactionError, SealedBlock, EIP1559_TX_TYPE_ID, EIP2930_TX_TYPE_ID,
|
||||||
EIP4844_TX_TYPE_ID, LEGACY_TX_TYPE_ID,
|
EIP4844_TX_TYPE_ID, LEGACY_TX_TYPE_ID,
|
||||||
@ -209,6 +212,26 @@ where
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let blob_count = transaction.blob_count();
|
||||||
|
if blob_count == 0 {
|
||||||
|
// no blobs
|
||||||
|
return TransactionValidationOutcome::Invalid(
|
||||||
|
transaction,
|
||||||
|
InvalidPoolTransactionError::NoEip4844Blobs,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if blob_count > MAX_BLOBS_PER_BLOCK {
|
||||||
|
// too many blobs
|
||||||
|
return TransactionValidationOutcome::Invalid(
|
||||||
|
transaction,
|
||||||
|
InvalidPoolTransactionError::TooManyEip4844Blobs {
|
||||||
|
have: blob_count,
|
||||||
|
permitted: MAX_BLOBS_PER_BLOCK,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// extract the blob from the transaction
|
// extract the blob from the transaction
|
||||||
match transaction.take_blob() {
|
match transaction.take_blob() {
|
||||||
EthBlobTransactionSidecar::None => {
|
EthBlobTransactionSidecar::None => {
|
||||||
@ -224,7 +247,7 @@ where
|
|||||||
} else {
|
} else {
|
||||||
return TransactionValidationOutcome::Invalid(
|
return TransactionValidationOutcome::Invalid(
|
||||||
transaction,
|
transaction,
|
||||||
InvalidPoolTransactionError::MissingEip4844Blob,
|
InvalidPoolTransactionError::MissingEip4844BlobSidecar,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user