feat: track max blobcount in forktracker (#14231)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Steven
2025-02-05 14:46:40 -06:00
committed by GitHub
parent 42a1912224
commit 9ac96e9393

View File

@ -19,8 +19,7 @@ use alloy_consensus::{
BlockHeader,
};
use alloy_eips::{
eip1559::ETHEREUM_BLOCK_GAS_LIMIT,
eip4844::{env_settings::EnvKzgSettings, MAX_BLOBS_PER_BLOCK},
eip1559::ETHEREUM_BLOCK_GAS_LIMIT, eip4844::env_settings::EnvKzgSettings, eip7840::BlobParams,
};
use reth_chainspec::{ChainSpecProvider, EthChainSpec, EthereumHardforks};
use reth_primitives::{InvalidTransactionError, SealedBlock};
@ -340,14 +339,14 @@ where
)
}
if blob_count > MAX_BLOBS_PER_BLOCK {
// too many blobs
let max_blob_count = self.fork_tracker.max_blob_count() as usize;
if blob_count > max_blob_count {
return TransactionValidationOutcome::Invalid(
transaction,
InvalidPoolTransactionError::Eip4844(
Eip4844PoolTransactionError::TooManyEip4844Blobs {
have: blob_count,
permitted: MAX_BLOBS_PER_BLOCK,
permitted: max_blob_count,
},
),
)
@ -527,6 +526,14 @@ where
self.fork_tracker.prague.store(true, std::sync::atomic::Ordering::Relaxed);
}
if let Some(blob_params) =
self.chain_spec().blob_params_at_timestamp(new_tip_block.timestamp())
{
self.fork_tracker
.max_blob_count
.store(blob_params.max_blob_count, std::sync::atomic::Ordering::Relaxed);
}
self.block_gas_limit.store(new_tip_block.gas_limit(), std::sync::atomic::Ordering::Relaxed);
}
@ -545,6 +552,8 @@ pub struct EthTransactionValidatorBuilder<Client> {
cancun: bool,
/// Fork indicator whether we are in the Cancun hardfork.
prague: bool,
/// Max blob count at the block's timestamp.
max_blob_count: u64,
/// Whether using EIP-2718 type transactions is allowed
eip2718: bool,
/// Whether using EIP-1559 type transactions is allowed
@ -603,6 +612,9 @@ impl<Client> EthTransactionValidatorBuilder<Client> {
// prague not yet activated
prague: false,
// max blob count is cancun by default
max_blob_count: BlobParams::cancun().max_blob_count,
}
}
@ -709,6 +721,12 @@ impl<Client> EthTransactionValidatorBuilder<Client> {
self.cancun = self.client.chain_spec().is_cancun_active_at_timestamp(timestamp);
self.shanghai = self.client.chain_spec().is_shanghai_active_at_timestamp(timestamp);
self.prague = self.client.chain_spec().is_prague_active_at_timestamp(timestamp);
self.max_blob_count = self
.client
.chain_spec()
.blob_params_at_timestamp(timestamp)
.unwrap_or_else(BlobParams::cancun)
.max_blob_count;
self
}
@ -748,10 +766,17 @@ impl<Client> EthTransactionValidatorBuilder<Client> {
..
} = self;
let max_blob_count = if prague {
BlobParams::prague().max_blob_count
} else {
BlobParams::cancun().max_blob_count
};
let fork_tracker = ForkTracker {
shanghai: AtomicBool::new(shanghai),
cancun: AtomicBool::new(cancun),
prague: AtomicBool::new(prague),
max_blob_count: AtomicU64::new(max_blob_count),
};
let inner = EthTransactionValidatorInner {
@ -825,6 +850,8 @@ pub struct ForkTracker {
pub cancun: AtomicBool,
/// Tracks if prague is activated at the block's timestamp.
pub prague: AtomicBool,
/// Tracks max blob count at the block's timestamp.
pub max_blob_count: AtomicU64,
}
impl ForkTracker {
@ -842,6 +869,11 @@ impl ForkTracker {
pub fn is_prague_activated(&self) -> bool {
self.prague.load(std::sync::atomic::Ordering::Relaxed)
}
/// Returns the max blob count.
pub fn max_blob_count(&self) -> u64 {
self.max_blob_count.load(std::sync::atomic::Ordering::Relaxed)
}
}
/// Ensures that gas limit of the transaction exceeds the intrinsic gas of the transaction.
@ -902,8 +934,12 @@ mod tests {
#[tokio::test]
async fn validate_transaction() {
let transaction = get_transaction();
let mut fork_tracker =
ForkTracker { shanghai: false.into(), cancun: false.into(), prague: false.into() };
let mut fork_tracker = ForkTracker {
shanghai: false.into(),
cancun: false.into(),
prague: false.into(),
max_blob_count: 0.into(),
};
let res = ensure_intrinsic_gas(&transaction, &fork_tracker);
assert!(res.is_ok());