From 297e8870c2e8215ff1e351c8ef8e2fc4bee8d448 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 5 Sep 2023 15:07:56 +0200 Subject: [PATCH] perf: skip blobs if no blob space available (#4480) --- crates/payload/basic/src/lib.rs | 14 ++++++++++---- crates/transaction-pool/src/pool/best.rs | 8 ++++++++ crates/transaction-pool/src/traits.rs | 16 ++++++++++++++-- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 49307b506..d7fbecd06 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -24,9 +24,8 @@ use reth_primitives::{ bytes::{Bytes, BytesMut}, calculate_excess_blob_gas, constants::{ - eip4844::{DATA_GAS_PER_BLOB, MAX_DATA_GAS_PER_BLOCK}, - BEACON_NONCE, EMPTY_RECEIPTS, EMPTY_TRANSACTIONS, EMPTY_WITHDRAWALS, - ETHEREUM_BLOCK_GAS_LIMIT, RETH_CLIENT_VERSION, SLOT_DURATION, + eip4844::MAX_DATA_GAS_PER_BLOCK, BEACON_NONCE, EMPTY_RECEIPTS, EMPTY_TRANSACTIONS, + EMPTY_WITHDRAWALS, ETHEREUM_BLOCK_GAS_LIMIT, RETH_CLIENT_VERSION, SLOT_DURATION, }, proofs, Block, BlockNumberOrTag, ChainSpec, Header, IntoRecoveredTransaction, Receipt, SealedBlock, Withdrawal, EMPTY_OMMER_ROOT, H256, U256, @@ -682,8 +681,10 @@ where // convert tx to a signed transaction let tx = pool_tx.to_recovered_transaction(); + // 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 if let Some(blob_tx) = tx.transaction.as_eip4844() { - let tx_blob_gas = blob_tx.blob_versioned_hashes.len() as u64 * DATA_GAS_PER_BLOB; + let tx_blob_gas = blob_tx.blob_gas(); if sum_blob_gas_used + tx_blob_gas > MAX_DATA_GAS_PER_BLOCK { // we can't fit this _blob_ transaction into the block, so we mark it as invalid, // which removes its dependent transactions from the iterator. This is similar to @@ -693,6 +694,11 @@ where } else { // add to the data gas if we're going to execute the transaction sum_blob_gas_used += tx_blob_gas; + + // if we've reached the max data gas per block, we can skip blob txs entirely + if sum_blob_gas_used == MAX_DATA_GAS_PER_BLOCK { + best_txs.skip_blobs(); + } } } diff --git a/crates/transaction-pool/src/pool/best.rs b/crates/transaction-pool/src/pool/best.rs index 2a57f2f22..fccb4c55b 100644 --- a/crates/transaction-pool/src/pool/best.rs +++ b/crates/transaction-pool/src/pool/best.rs @@ -30,6 +30,10 @@ impl crate::traits::BestTransactions for BestTransaction self.best.no_updates() } + fn skip_blobs(&mut self) { + self.set_skip_blobs(true) + } + fn set_skip_blobs(&mut self, skip_blobs: bool) { self.best.set_skip_blobs(skip_blobs) } @@ -141,6 +145,10 @@ impl crate::traits::BestTransactions for BestTransaction self.new_transaction_receiver.take(); } + fn skip_blobs(&mut self) { + self.set_skip_blobs(true); + } + fn set_skip_blobs(&mut self, skip_blobs: bool) { self.skip_blobs = skip_blobs; } diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index 0df53ed51..49badfd05 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -580,9 +580,19 @@ pub trait BestTransactions: Iterator + Send { /// listen to pool updates. fn no_updates(&mut self); - /// Set the skip_blobs flag to control whether to skip blob transactions (is_eip4844). + /// Skip all blob transactions. /// - /// This flag will control whether the iterator skips blob transactions or not. + /// There's only limited blob space available in a block, once exhausted, EIP-4844 transactions + /// can no longer be included. + /// + /// If called then the iterator will no longer yield blob transactions. + /// + /// Note: this will also exclude any transactions that depend on blob transactions. + fn skip_blobs(&mut self); + + /// Controls whether the iterator skips blob transactions or not. + /// + /// If set to true, no blob transactions will be returned. fn set_skip_blobs(&mut self, skip_blobs: bool); } @@ -592,6 +602,8 @@ impl BestTransactions for std::iter::Empty { fn no_updates(&mut self) {} + fn skip_blobs(&mut self) {} + fn set_skip_blobs(&mut self, _skip_blobs: bool) {} }