From a041b41b59c9e0dafdef08889c9cc7783539ae2c Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Sat, 1 Feb 2025 16:41:22 +0000 Subject: [PATCH] chore: use chainspec `blob_params` for blob calculations (#14139) --- crates/ethereum/payload/src/lib.rs | 2 +- crates/node/builder/src/rpc.rs | 9 +++++-- crates/optimism/rpc/src/eth/receipt.rs | 2 +- crates/rpc/rpc-eth-types/src/fee_history.rs | 30 ++++++++++++++------- crates/rpc/rpc-eth-types/src/receipt.rs | 21 ++++++++++----- crates/rpc/rpc/src/eth/helpers/block.rs | 8 +++--- crates/rpc/rpc/src/eth/helpers/receipt.rs | 8 +++--- 7 files changed, 55 insertions(+), 25 deletions(-) diff --git a/crates/ethereum/payload/src/lib.rs b/crates/ethereum/payload/src/lib.rs index 916426118f6c..c4e689ed6e60 100644 --- a/crates/ethereum/payload/src/lib.rs +++ b/crates/ethereum/payload/src/lib.rs @@ -424,7 +424,7 @@ where } else { // for the first post-fork block, both parent.blob_gas_used and // parent.excess_blob_gas are evaluated as 0 - Some(alloy_eips::eip4844::calc_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); diff --git a/crates/node/builder/src/rpc.rs b/crates/node/builder/src/rpc.rs index e42193913056..cb1ac212ce52 100644 --- a/crates/node/builder/src/rpc.rs +++ b/crates/node/builder/src/rpc.rs @@ -19,6 +19,7 @@ use reth_node_core::{ }; use reth_payload_builder::PayloadStore; use reth_primitives::EthPrimitives; +use reth_provider::ChainSpecProvider; use reth_rpc::{ eth::{EthApiTypes, FullEthApiServer}, EthApi, @@ -571,8 +572,12 @@ pub trait EthApiBuilder: 'static { fn build(ctx: &EthApiBuilderCtx) -> Self; } -impl>> EthApiBuilder - for EthApi +impl< + N: FullNodeComponents< + Provider: ChainSpecProvider, + Types: NodeTypes, + >, + > EthApiBuilder for EthApi { fn build(ctx: &EthApiBuilderCtx) -> Self { Self::with_spawner(ctx) diff --git a/crates/optimism/rpc/src/eth/receipt.rs b/crates/optimism/rpc/src/eth/receipt.rs index 2ea10e1cb1f5..cd37a8d24886 100644 --- a/crates/optimism/rpc/src/eth/receipt.rs +++ b/crates/optimism/rpc/src/eth/receipt.rs @@ -203,7 +203,7 @@ impl OpReceiptBuilder { ) -> Result { let timestamp = meta.timestamp; let core_receipt = - build_receipt(transaction, meta, receipt, all_receipts, |receipt_with_bloom| { + build_receipt(transaction, meta, receipt, all_receipts, None, |receipt_with_bloom| { match receipt { OpReceipt::Legacy(_) => OpReceiptEnvelope::::Legacy(receipt_with_bloom), OpReceipt::Eip2930(_) => OpReceiptEnvelope::::Eip2930(receipt_with_bloom), diff --git a/crates/rpc/rpc-eth-types/src/fee_history.rs b/crates/rpc/rpc-eth-types/src/fee_history.rs index fdf0d2730ae3..80a593360593 100644 --- a/crates/rpc/rpc-eth-types/src/fee_history.rs +++ b/crates/rpc/rpc-eth-types/src/fee_history.rs @@ -7,7 +7,7 @@ use std::{ }; use alloy_consensus::{BlockHeader, Transaction, TxReceipt}; -use alloy_eips::eip1559::calc_next_block_base_fee; +use alloy_eips::{eip1559::calc_next_block_base_fee, eip7840::BlobParams}; use alloy_primitives::B256; use alloy_rpc_types_eth::TxGasAndReward; use futures::{ @@ -72,18 +72,22 @@ impl FeeHistoryCache { } /// Insert block data into the cache. - async fn insert_blocks<'a, I, B, R>(&self, blocks: I) + async fn insert_blocks<'a, I, B, R, C>(&self, blocks: I, chain_spec: &C) where B: Block + 'a, R: TxReceipt, I: IntoIterator, Arc>)>, + C: EthChainSpec, { let mut entries = self.inner.entries.write().await; let percentiles = self.predefined_percentiles(); // Insert all new blocks and calculate approximated rewards for (block, receipts) in blocks { - let mut fee_history_entry = FeeHistoryEntry::new(block); + let mut fee_history_entry = FeeHistoryEntry::new( + block, + chain_spec.blob_params_at_timestamp(block.header().timestamp()), + ); fee_history_entry.rewards = calculate_reward_percentiles_for_block( &percentiles, fee_history_entry.gas_used, @@ -232,12 +236,14 @@ pub async fn fee_history_cache_new_blocks_task( } } + let chain_spec = provider.chain_spec(); + tokio::select! { res = &mut fetch_missing_block => { if let Ok(res) = res { let res = res.as_ref() .map(|(b, r)| (b.sealed_block(), r.clone())); - fee_history_cache.insert_blocks(res).await; + fee_history_cache.insert_blocks(res, &chain_spec).await; } } event = events.next() => { @@ -253,7 +259,7 @@ pub async fn fee_history_cache_new_blocks_task( (block.clone_sealed_block(), Arc::new(receipts.clone())) }) .unzip(); - fee_history_cache.insert_blocks(blocks.iter().zip(receipts)).await; + fee_history_cache.insert_blocks(blocks.iter().zip(receipts), &chain_spec).await; // keep track of missing blocks missing_blocks = fee_history_cache.missing_consecutive_blocks().await; @@ -356,20 +362,22 @@ pub struct FeeHistoryEntry { pub rewards: Vec, /// The timestamp of the block. pub timestamp: u64, + /// Blob parameters for this block. + pub blob_params: Option, } impl FeeHistoryEntry { /// Creates a new entry from a sealed block. /// /// Note: This does not calculate the rewards for the block. - pub fn new(block: &SealedBlock) -> Self { + pub fn new(block: &SealedBlock, blob_params: Option) -> Self { Self { base_fee_per_gas: block.header().base_fee_per_gas().unwrap_or_default(), gas_used_ratio: block.header().gas_used() as f64 / block.header().gas_limit() as f64, base_fee_per_blob_gas: block .header() .excess_blob_gas() - .map(alloy_eips::eip4844::calc_blob_gasprice), + .and_then(|excess_blob_gas| Some(blob_params?.calc_blob_fee(excess_blob_gas))), blob_gas_used_ratio: block.body().blob_gas_used() as f64 / alloy_eips::eip4844::MAX_DATA_GAS_PER_BLOCK as f64, excess_blob_gas: block.header().excess_blob_gas(), @@ -379,6 +387,7 @@ impl FeeHistoryEntry { gas_limit: block.header().gas_limit(), rewards: Vec::new(), timestamp: block.header().timestamp(), + blob_params, } } @@ -398,13 +407,16 @@ impl FeeHistoryEntry { /// /// See also [`Self::next_block_excess_blob_gas`] pub fn next_block_blob_fee(&self) -> Option { - self.next_block_excess_blob_gas().map(alloy_eips::eip4844::calc_blob_gasprice) + self.next_block_excess_blob_gas() + .and_then(|excess_blob_gas| Some(self.blob_params?.calc_blob_fee(excess_blob_gas))) } /// Calculate excess blob gas for the next block according to the EIP-4844 spec. /// /// Returns a `None` if no excess blob gas is set, no EIP-4844 support pub fn next_block_excess_blob_gas(&self) -> Option { - Some(alloy_eips::eip4844::calc_excess_blob_gas(self.excess_blob_gas?, self.blob_gas_used?)) + self.excess_blob_gas.and_then(|excess_blob_gas| { + Some(self.blob_params?.next_block_excess_blob_gas(excess_blob_gas, self.blob_gas_used?)) + }) } } diff --git a/crates/rpc/rpc-eth-types/src/receipt.rs b/crates/rpc/rpc-eth-types/src/receipt.rs index 3b914516ad03..07688ba38f2f 100644 --- a/crates/rpc/rpc-eth-types/src/receipt.rs +++ b/crates/rpc/rpc-eth-types/src/receipt.rs @@ -2,6 +2,7 @@ use super::EthResult; use alloy_consensus::{transaction::TransactionMeta, ReceiptEnvelope, TxReceipt}; +use alloy_eips::eip7840::BlobParams; use alloy_primitives::{Address, TxKind}; use alloy_rpc_types_eth::{Log, ReceiptWithBloom, TransactionReceipt}; use reth_primitives::{Receipt, TransactionSigned, TxType}; @@ -13,6 +14,7 @@ pub fn build_receipt( meta: TransactionMeta, receipt: &R, all_receipts: &[R], + blob_params: Option, build_envelope: impl FnOnce(ReceiptWithBloom>) -> E, ) -> EthResult> where @@ -36,8 +38,9 @@ where let blob_gas_used = transaction.blob_gas_used(); // Blob gas price should only be present if the transaction is a blob transaction - let blob_gas_price = blob_gas_used - .and_then(|_| meta.excess_blob_gas.map(alloy_eips::eip4844::calc_blob_gasprice)); + let blob_gas_price = + blob_gas_used.and_then(|_| Some(blob_params?.calc_blob_fee(meta.excess_blob_gas?))); + let logs_bloom = receipt.bloom(); // get number of logs in the block @@ -107,9 +110,15 @@ impl EthReceiptBuilder { meta: TransactionMeta, receipt: &Receipt, all_receipts: &[Receipt], + blob_params: Option, ) -> EthResult { - let base = build_receipt(transaction, meta, receipt, all_receipts, |receipt_with_bloom| { - match receipt.tx_type { + let base = build_receipt( + transaction, + meta, + receipt, + all_receipts, + blob_params, + |receipt_with_bloom| match receipt.tx_type { TxType::Legacy => ReceiptEnvelope::Legacy(receipt_with_bloom), TxType::Eip2930 => ReceiptEnvelope::Eip2930(receipt_with_bloom), TxType::Eip1559 => ReceiptEnvelope::Eip1559(receipt_with_bloom), @@ -117,8 +126,8 @@ impl EthReceiptBuilder { TxType::Eip7702 => ReceiptEnvelope::Eip7702(receipt_with_bloom), #[allow(unreachable_patterns)] _ => unreachable!(), - } - })?; + }, + )?; Ok(Self { base }) } diff --git a/crates/rpc/rpc/src/eth/helpers/block.rs b/crates/rpc/rpc/src/eth/helpers/block.rs index c23f327848b4..31efb0936c21 100644 --- a/crates/rpc/rpc/src/eth/helpers/block.rs +++ b/crates/rpc/rpc/src/eth/helpers/block.rs @@ -2,8 +2,9 @@ use alloy_consensus::{transaction::TransactionMeta, BlockHeader}; use alloy_rpc_types_eth::{BlockId, TransactionReceipt}; +use reth_chainspec::EthChainSpec; use reth_primitives_traits::{BlockBody, SignedTransaction}; -use reth_provider::BlockReader; +use reth_provider::{BlockReader, ChainSpecProvider}; use reth_rpc_eth_api::{ helpers::{EthBlocks, LoadBlock, LoadPendingBlock, LoadReceipt, SpawnBlocking}, RpcNodeCoreExt, RpcReceipt, @@ -22,7 +23,7 @@ where Receipt = reth_primitives::Receipt, >, >, - Provider: BlockReader, + Provider: BlockReader + ChainSpecProvider, { async fn block_receipts( &self, @@ -37,6 +38,7 @@ where let block_hash = block.hash(); let excess_blob_gas = block.excess_blob_gas(); let timestamp = block.timestamp(); + let blob_params = self.provider().chain_spec().blob_params_at_timestamp(timestamp); return block .body() @@ -54,7 +56,7 @@ where excess_blob_gas, timestamp, }; - EthReceiptBuilder::new(tx, meta, receipt, &receipts) + EthReceiptBuilder::new(tx, meta, receipt, &receipts, blob_params) .map(|builder| builder.build()) }) .collect::, Self::Error>>() diff --git a/crates/rpc/rpc/src/eth/helpers/receipt.rs b/crates/rpc/rpc/src/eth/helpers/receipt.rs index 4b88e2f6f33b..9cede0ebdf10 100644 --- a/crates/rpc/rpc/src/eth/helpers/receipt.rs +++ b/crates/rpc/rpc/src/eth/helpers/receipt.rs @@ -1,8 +1,9 @@ //! Builds an RPC receipt response w.r.t. data layout of network. use alloy_consensus::transaction::TransactionMeta; +use reth_chainspec::EthChainSpec; use reth_primitives::{Receipt, TransactionSigned}; -use reth_provider::{BlockReader, ReceiptProvider, TransactionsProvider}; +use reth_provider::{BlockReader, ChainSpecProvider, ReceiptProvider, TransactionsProvider}; use reth_rpc_eth_api::{helpers::LoadReceipt, FromEthApiError, RpcNodeCoreExt, RpcReceipt}; use reth_rpc_eth_types::{EthApiError, EthReceiptBuilder}; @@ -14,7 +15,7 @@ where Provider: TransactionsProvider + ReceiptProvider, >, - Provider: BlockReader, + Provider: BlockReader + ChainSpecProvider, { async fn build_transaction_receipt( &self, @@ -30,7 +31,8 @@ where .await .map_err(Self::Error::from_eth_err)? .ok_or(EthApiError::HeaderNotFound(hash.into()))?; + let blob_params = self.provider().chain_spec().blob_params_at_timestamp(meta.timestamp); - Ok(EthReceiptBuilder::new(&tx, meta, &receipt, &all_receipts)?.build()) + Ok(EthReceiptBuilder::new(&tx, meta, &receipt, &all_receipts, blob_params)?.build()) } }