diff --git a/crates/rpc/rpc/src/eth/api/fee_history.rs b/crates/rpc/rpc/src/eth/api/fee_history.rs index 5211063307b3..2bb5b0319c68 100644 --- a/crates/rpc/rpc/src/eth/api/fee_history.rs +++ b/crates/rpc/rpc/src/eth/api/fee_history.rs @@ -5,8 +5,12 @@ use futures::{ future::{Fuse, FusedFuture}, FutureExt, Stream, StreamExt, }; + use metrics::atomics::AtomicU64; -use reth_primitives::{Receipt, SealedBlock, TransactionSigned, B256, U256}; +use reth_primitives::{ + eip4844::{calc_blob_gasprice, calculate_excess_blob_gas}, + Receipt, SealedBlock, TransactionSigned, B256, U256, +}; use reth_provider::{BlockReaderIdExt, CanonStateNotification, ChainSpecProvider}; use reth_rpc_types::TxGasAndReward; use serde::{Deserialize, Serialize}; @@ -324,6 +328,17 @@ pub struct FeeHistoryEntry { pub base_fee_per_gas: u64, /// Gas used ratio this block. pub gas_used_ratio: f64, + /// The base per blob gas for EIP-4844. + /// For pre EIP-4844 equals to zero. + pub base_fee_per_blob_gas: Option, + /// Blob gas used ratio for this block. + /// Calculated as the ratio pf gasUsed and gasLimit. + pub blob_gas_used_ratio: f64, + /// The excess blob gas of the block. + pub excess_blob_gas: Option, + /// The total amount of blob gas consumed by the transactions within the block, + /// added in EIP-4844 + pub blob_gas_used: Option, /// Gas used by this block. pub gas_used: u64, /// Gas limit by this block. @@ -342,10 +357,31 @@ impl FeeHistoryEntry { FeeHistoryEntry { base_fee_per_gas: block.base_fee_per_gas.unwrap_or_default(), gas_used_ratio: block.gas_used as f64 / block.gas_limit as f64, + base_fee_per_blob_gas: block.blob_fee(), + blob_gas_used_ratio: block.blob_gas_used() as f64 / + reth_primitives::constants::eip4844::MAX_DATA_GAS_PER_BLOCK as f64, + excess_blob_gas: block.excess_blob_gas, + blob_gas_used: block.blob_gas_used, gas_used: block.gas_used, header_hash: block.hash(), gas_limit: block.gas_limit, rewards: Vec::new(), } } + + /// Returns the blob fee for the next block according to the EIP-4844 spec. + /// + /// Returns `None` if `excess_blob_gas` is None. + /// + /// See also [Self::next_block_excess_blob_gas] + pub fn next_block_blob_fee(&self) -> Option { + self.next_block_excess_blob_gas().map(calc_blob_gasprice) + } + + /// 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(calculate_excess_blob_gas(self.excess_blob_gas?, self.blob_gas_used?)) + } } diff --git a/crates/rpc/rpc/src/eth/api/fees.rs b/crates/rpc/rpc/src/eth/api/fees.rs index 4923854efc2d..49c7682fc9be 100644 --- a/crates/rpc/rpc/src/eth/api/fees.rs +++ b/crates/rpc/rpc/src/eth/api/fees.rs @@ -109,6 +109,10 @@ where // Collect base fees, gas usage ratios and (optionally) reward percentile data let mut base_fee_per_gas: Vec = Vec::new(); let mut gas_used_ratio: Vec = Vec::new(); + + let mut base_fee_per_blob_gas: Vec = Vec::new(); + let mut blob_gas_used_ratio: Vec = Vec::new(); + let mut rewards: Vec> = Vec::new(); // Check if the requested range is within the cache bounds @@ -122,6 +126,9 @@ where for entry in &fee_entries { base_fee_per_gas.push(U256::from(entry.base_fee_per_gas)); gas_used_ratio.push(entry.gas_used_ratio); + base_fee_per_blob_gas + .push(U256::from(entry.base_fee_per_blob_gas.unwrap_or_default())); + blob_gas_used_ratio.push(entry.blob_gas_used_ratio); if let Some(percentiles) = &reward_percentiles { let mut block_rewards = Vec::with_capacity(percentiles.len()); @@ -139,12 +146,17 @@ where .map(|h| h.timestamp) .unwrap_or_default(); + // Als need to include the `base_fee_per_gas` and `base_fee_per_blob_gas` for the next + // block base_fee_per_gas.push(U256::from(calculate_next_block_base_fee( last_entry.gas_used, last_entry.gas_limit, last_entry.base_fee_per_gas, self.provider().chain_spec().base_fee_params(last_entry_timestamp), ))); + + base_fee_per_blob_gas + .push(U256::from(last_entry.next_block_blob_fee().unwrap_or_default())); } else { // read the requested header range let headers = self.provider().sealed_headers_range(start_block..=end_block)?; @@ -155,6 +167,11 @@ where for header in &headers { base_fee_per_gas.push(U256::from(header.base_fee_per_gas.unwrap_or_default())); gas_used_ratio.push(header.gas_used as f64 / header.gas_limit as f64); + base_fee_per_blob_gas.push(U256::from(header.blob_fee().unwrap_or_default())); + blob_gas_used_ratio.push( + header.blob_gas_used.unwrap_or_default() as f64 / + reth_primitives::constants::eip4844::MAX_DATA_GAS_PER_BLOCK as f64, + ); // Percentiles were specified, so we need to collect reward percentile ino if let Some(percentiles) = &reward_percentiles { @@ -194,15 +211,19 @@ where last_header.base_fee_per_gas.unwrap_or_default(), self.provider().chain_spec().base_fee_params(last_header.timestamp), ))); + + // Same goes for the `base_fee_per_blob_gas` + base_fee_per_blob_gas + .push(U256::from(last_header.next_block_blob_fee().unwrap_or_default())); }; Ok(FeeHistory { base_fee_per_gas, gas_used_ratio, + base_fee_per_blob_gas, + blob_gas_used_ratio, oldest_block: U256::from(start_block), reward: reward_percentiles.map(|_| rewards), - base_fee_per_blob_gas: Default::default(), - blob_gas_used_ratio: Default::default(), }) }