fix: use blob params in payload building (#14217)

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
Arpit Temani
2025-02-05 18:37:42 +05:30
committed by GitHub
parent 8d35f26db9
commit ab804d4650

View File

@ -10,9 +10,7 @@
#![allow(clippy::useless_let_if_seq)] #![allow(clippy::useless_let_if_seq)]
use alloy_consensus::{BlockHeader, Header, Transaction, Typed2718, EMPTY_OMMER_ROOT_HASH}; use alloy_consensus::{BlockHeader, Header, Transaction, Typed2718, EMPTY_OMMER_ROOT_HASH};
use alloy_eips::{ use alloy_eips::{eip4844::DATA_GAS_PER_BLOB, eip6110, eip7685::Requests, merge::BEACON_NONCE};
eip4844::MAX_DATA_GAS_PER_BLOCK, eip6110, eip7685::Requests, merge::BEACON_NONCE,
};
use alloy_primitives::U256; use alloy_primitives::U256;
use reth_basic_payload_builder::{ use reth_basic_payload_builder::{
commit_withdrawals, is_better_payload, BuildArguments, BuildOutcome, PayloadBuilder, commit_withdrawals, is_better_payload, BuildArguments, BuildOutcome, PayloadBuilder,
@ -52,6 +50,7 @@ use tracing::{debug, trace, warn};
mod config; mod config;
pub use config::*; pub use config::*;
use reth_transaction_pool::error::Eip4844PoolTransactionError;
type BestTransactionsIter<Pool> = Box< type BestTransactionsIter<Pool> = Box<
dyn BestTransactions<Item = Arc<ValidPoolTransaction<<Pool as TransactionPool>::Transaction>>>, dyn BestTransactions<Item = Arc<ValidPoolTransaction<<Pool as TransactionPool>::Transaction>>>,
@ -185,7 +184,6 @@ where
debug!(target: "payload_builder", id=%attributes.id, parent_header = ?parent_header.hash(), parent_number = parent_header.number, "building new payload"); debug!(target: "payload_builder", id=%attributes.id, parent_header = ?parent_header.hash(), parent_number = parent_header.number, "building new payload");
let mut cumulative_gas_used = 0; let mut cumulative_gas_used = 0;
let mut sum_blob_gas_used = 0;
let block_gas_limit: u64 = evm_env.block_env.gas_limit.to::<u64>(); let block_gas_limit: u64 = evm_env.block_env.gas_limit.to::<u64>();
let base_fee = evm_env.block_env.basefee.to::<u64>(); let base_fee = evm_env.block_env.basefee.to::<u64>();
@ -228,6 +226,11 @@ where
let mut evm = evm_config.evm_with_env(&mut db, evm_env); let mut evm = evm_config.evm_with_env(&mut db, evm_env);
let mut receipts = Vec::new(); let mut receipts = Vec::new();
let mut block_blob_count = 0;
let blob_params = chain_spec.blob_params_at_timestamp(attributes.timestamp);
let max_blob_count =
blob_params.as_ref().map(|params| params.max_blob_count).unwrap_or_default();
while let Some(pool_tx) = best_txs.next() { while let Some(pool_tx) = best_txs.next() {
// ensure we still have capacity for this transaction // ensure we still have capacity for this transaction
if cumulative_gas_used + pool_tx.gas_limit() > block_gas_limit { if cumulative_gas_used + pool_tx.gas_limit() > block_gas_limit {
@ -252,18 +255,21 @@ where
// There's only limited amount of blob space available per block, so we need to check if // There's only limited amount of blob space available per block, so we need to check if
// the EIP-4844 can still fit in the block // the EIP-4844 can still fit in the block
if let Some(blob_tx) = tx.as_eip4844() { if let Some(blob_tx) = tx.as_eip4844() {
let tx_blob_gas = blob_tx.blob_gas(); let tx_blob_count = blob_tx.blob_versioned_hashes.len() as u64;
if sum_blob_gas_used + tx_blob_gas > MAX_DATA_GAS_PER_BLOCK {
if block_blob_count + tx_blob_count > max_blob_count {
// we can't fit this _blob_ transaction into the block, so we mark it as // we can't fit this _blob_ transaction into the block, so we mark it as
// invalid, which removes its dependent transactions from // invalid, which removes its dependent transactions from
// the iterator. This is similar to the gas limit condition // the iterator. This is similar to the gas limit condition
// for regular transactions above. // for regular transactions above.
trace!(target: "payload_builder", tx=?tx.hash(), ?sum_blob_gas_used, ?tx_blob_gas, "skipping blob transaction because it would exceed the max data gas per block"); trace!(target: "payload_builder", tx=?tx.hash(), ?block_blob_count, "skipping blob transaction because it would exceed the max blob count per block");
best_txs.mark_invalid( best_txs.mark_invalid(
&pool_tx, &pool_tx,
InvalidPoolTransactionError::ExceedsGasLimit( InvalidPoolTransactionError::Eip4844(
tx_blob_gas, Eip4844PoolTransactionError::TooManyEip4844Blobs {
MAX_DATA_GAS_PER_BLOCK, have: (block_blob_count + tx_blob_count) as usize,
permitted: max_blob_count as usize,
},
), ),
); );
continue continue
@ -303,11 +309,10 @@ where
// add to the total blob gas used if the transaction successfully executed // add to the total blob gas used if the transaction successfully executed
if let Some(blob_tx) = tx.as_eip4844() { if let Some(blob_tx) = tx.as_eip4844() {
let tx_blob_gas = blob_tx.blob_gas(); block_blob_count += blob_tx.blob_versioned_hashes.len() as u64;
sum_blob_gas_used += tx_blob_gas;
// if we've reached the max data gas per block, we can skip blob txs entirely // if we've reached the max blob count, we can skip blob txs entirely
if sum_blob_gas_used == MAX_DATA_GAS_PER_BLOCK { if block_blob_count == max_blob_count {
best_txs.skip_blobs(); best_txs.skip_blobs();
} }
} }
@ -418,16 +423,14 @@ where
.map_err(PayloadBuilderError::other)?; .map_err(PayloadBuilderError::other)?;
excess_blob_gas = if chain_spec.is_cancun_active_at_timestamp(parent_header.timestamp) { excess_blob_gas = if chain_spec.is_cancun_active_at_timestamp(parent_header.timestamp) {
parent_header.maybe_next_block_excess_blob_gas( parent_header.maybe_next_block_excess_blob_gas(blob_params)
chain_spec.blob_params_at_timestamp(attributes.timestamp),
)
} else { } else {
// for the first post-fork block, both parent.blob_gas_used and // for the first post-fork block, both parent.blob_gas_used and
// parent.excess_blob_gas are evaluated as 0 // parent.excess_blob_gas are evaluated as 0
Some(alloy_eips::eip7840::BlobParams::cancun().next_block_excess_blob_gas(0, 0)) Some(alloy_eips::eip7840::BlobParams::cancun().next_block_excess_blob_gas(0, 0))
}; };
blob_gas_used = Some(sum_blob_gas_used); blob_gas_used = Some(block_blob_count * DATA_GAS_PER_BLOB);
} }
let header = Header { let header = Header {