From 0ca76e8f3f80aba87d74ffd42671c6b58ae62a8c Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Wed, 27 Nov 2024 20:55:08 +0400 Subject: [PATCH] feat: EIP-7742 (#1600) * basic utils and header update * payload attributes * sidecar * rename * fix * fmt * apply latest calc blob changes * doc --- crates/consensus-any/src/block/header.rs | 16 ++++ crates/consensus/src/block/header.rs | 111 +++++++++++++++++++++-- crates/eips/src/eip4844/mod.rs | 2 +- crates/eips/src/eip7742.rs | 65 +++++++++++++ crates/eips/src/lib.rs | 2 + crates/provider/src/fillers/gas.rs | 10 +- crates/rpc-types-beacon/src/payload.rs | 10 ++ crates/rpc-types-engine/src/lib.rs | 2 + crates/rpc-types-engine/src/payload.rs | 20 ++++ crates/rpc-types-engine/src/prague.rs | 63 +++++++++++++ crates/rpc-types-engine/src/sidecar.rs | 28 ++++-- crates/rpc-types-eth/src/block.rs | 10 ++ 12 files changed, 320 insertions(+), 19 deletions(-) create mode 100644 crates/eips/src/eip7742.rs create mode 100644 crates/rpc-types-engine/src/prague.rs diff --git a/crates/consensus-any/src/block/header.rs b/crates/consensus-any/src/block/header.rs index 9a6676e4a2f..212e23f7a54 100644 --- a/crates/consensus-any/src/block/header.rs +++ b/crates/consensus-any/src/block/header.rs @@ -95,6 +95,16 @@ pub struct AnyHeader { /// EIP-7685 requests hash. #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub requests_hash: Option, + /// EIP-7744 target blob count. + #[cfg_attr( + feature = "serde", + serde( + default, + with = "alloy_serde::quantity::opt", + skip_serializing_if = "Option::is_none" + ) + )] + pub target_blobs_per_block: Option, } impl BlockHeader for AnyHeader { @@ -178,6 +188,10 @@ impl BlockHeader for AnyHeader { self.requests_hash } + fn target_blobs_per_block(&self) -> Option { + self.target_blobs_per_block + } + fn extra_data(&self) -> &Bytes { &self.extra_data } @@ -207,6 +221,7 @@ impl From
for AnyHeader { excess_blob_gas, parent_beacon_block_root, requests_hash, + target_blobs_per_block, } = value; Self { @@ -231,6 +246,7 @@ impl From
for AnyHeader { excess_blob_gas, parent_beacon_block_root, requests_hash, + target_blobs_per_block, } } } diff --git a/crates/consensus/src/block/header.rs b/crates/consensus/src/block/header.rs index cc11b58d7aa..578fe1ce4f5 100644 --- a/crates/consensus/src/block/header.rs +++ b/crates/consensus/src/block/header.rs @@ -1,9 +1,11 @@ use crate::constants::{EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; use alloc::vec::Vec; use alloy_eips::{ + calc_blob_gasprice, eip1559::{calc_next_block_base_fee, BaseFeeParams}, eip1898::BlockWithParent, - eip4844::{calc_blob_gasprice, calc_excess_blob_gas}, + eip4844::{self}, + eip7742, merge::ALLOWED_FUTURE_BLOCK_TIME_SECONDS, BlockNumHash, }; @@ -125,6 +127,18 @@ pub struct Header { /// [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685 #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub requests_hash: Option, + /// The target number of blobs in the block, introduced in [EIP-7742]. + /// + /// [EIP-7742]: https://eips.ethereum.org/EIPS/eip-7742 + #[cfg_attr( + feature = "serde", + serde( + default, + with = "alloy_serde::quantity::opt", + skip_serializing_if = "Option::is_none" + ) + )] + pub target_blobs_per_block: Option, } impl AsRef for Header { @@ -157,6 +171,7 @@ impl Default for Header { excess_blob_gas: None, parent_beacon_block_root: None, requests_hash: None, + target_blobs_per_block: None, } } } @@ -206,9 +221,18 @@ impl Header { /// /// Returns `None` if `excess_blob_gas` is None. /// + /// If [`Self::target_blobs_per_block`] is [`Some`], uses EIP-7742 formula for calculating + /// the blob gas price, otherwise uses EIP-4844 formula. + /// /// 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) + let next_block_excess_blob_gas = self.next_block_excess_blob_gas()?; + + if self.target_blobs_per_block().is_none() { + Some(eip4844::calc_blob_gasprice(next_block_excess_blob_gas)) + } else { + Some(eip7742::calc_blob_gasprice(next_block_excess_blob_gas)) + } } /// Calculate base fee for next block according to the EIP-1559 spec. @@ -226,9 +250,27 @@ impl Header { /// Calculate excess blob gas for the next block according to the EIP-4844 /// spec. /// + /// If [`Self::target_blobs_per_block`] is [`Some`], uses EIP-7742 formula for calculating + /// the excess blob gas, otherwise uses EIP-4844 formula. + /// + /// Note: this function will return incorrect (unnormalized, lower) value at EIP-7742 activation + /// block. If this is undesired, consider using [`eip7742::calc_excess_blob_gas_at_transition`]. + /// /// Returns a `None` if no excess blob gas is set, no EIP-4844 support pub fn next_block_excess_blob_gas(&self) -> Option { - Some(calc_excess_blob_gas(self.excess_blob_gas?, self.blob_gas_used?)) + let excess_blob_gas = self.excess_blob_gas?; + let blob_gas_used = self.blob_gas_used?; + + Some(self.target_blobs_per_block.map_or_else( + || eip4844::calc_excess_blob_gas(excess_blob_gas, blob_gas_used), + |target_blobs_per_block| { + eip7742::calc_excess_blob_gas( + excess_blob_gas, + blob_gas_used, + target_blobs_per_block, + ) + }, + )) } /// Calculate a heuristic for the in-memory size of the [Header]. @@ -303,6 +345,10 @@ impl Header { length += requests_hash.length(); } + if let Some(target_blobs_per_block) = self.target_blobs_per_block { + length += target_blobs_per_block.length(); + } + length } @@ -403,6 +449,10 @@ impl Encodable for Header { if let Some(ref requests_hash) = self.requests_hash { requests_hash.encode(out); } + + if let Some(ref target_blobs_per_block) = self.target_blobs_per_block { + target_blobs_per_block.encode(out); + } } fn length(&self) -> usize { @@ -442,6 +492,7 @@ impl Decodable for Header { excess_blob_gas: None, parent_beacon_block_root: None, requests_hash: None, + target_blobs_per_block: None, }; if started_len - buf.len() < rlp_head.payload_length { this.base_fee_per_gas = Some(u64::decode(buf)?); @@ -471,6 +522,11 @@ impl Decodable for Header { this.requests_hash = Some(B256::decode(buf)?); } + // Decode target blob count. + if started_len - buf.len() < rlp_head.payload_length { + this.target_blobs_per_block = Some(u64::decode(buf)?); + } + let consumed = started_len - buf.len(); if consumed != rlp_head.payload_length { return Err(alloy_rlp::Error::ListLengthMismatch { @@ -547,6 +603,7 @@ impl<'a> arbitrary::Arbitrary<'a> for Header { parent_beacon_block_root: u.arbitrary()?, requests_hash: u.arbitrary()?, withdrawals_root: u.arbitrary()?, + target_blobs_per_block: u.arbitrary()?, }; Ok(generate_valid_header( @@ -622,24 +679,54 @@ pub trait BlockHeader { /// Retrieves the requests hash of the block, if available fn requests_hash(&self) -> Option; + /// Retrieves the target blob count of the block, if available + fn target_blobs_per_block(&self) -> Option; + /// Retrieves the block's extra data field fn extra_data(&self) -> &Bytes; /// Calculate excess blob gas for the next block according to the EIP-4844 /// spec. /// + /// If [`BlockHeader::target_blobs_per_block`] is [`Some`], uses EIP-7742 formula for + /// calculating the excess blob gas, otherwise uses EIP-4844 formula. + /// + /// Note: this function will return incorrect (unnormalized, lower) value at EIP-7742 activation + /// block. If this is undesired, consider using [`eip7742::calc_excess_blob_gas_at_transition`]. + /// /// Returns a `None` if no excess blob gas is set, no EIP-4844 support fn next_block_excess_blob_gas(&self) -> Option { - Some(calc_excess_blob_gas(self.excess_blob_gas()?, self.blob_gas_used()?)) + let excess_blob_gas = self.excess_blob_gas()?; + let blob_gas_used = self.blob_gas_used()?; + + Some(self.target_blobs_per_block().map_or_else( + || eip4844::calc_excess_blob_gas(excess_blob_gas, blob_gas_used), + |target_blobs_per_block| { + eip7742::calc_excess_blob_gas( + excess_blob_gas, + blob_gas_used, + target_blobs_per_block, + ) + }, + )) } /// 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] + /// If this header has `target_blobs_per_block` set, uses EIP-7742 formula for calculating + /// the blob gas price, otherwise uses EIP-4844 formula. + /// + /// See also [BlockHeader::next_block_excess_blob_gas] fn next_block_blob_fee(&self) -> Option { - self.next_block_excess_blob_gas().map(calc_blob_gasprice) + let next_block_excess_blob_gas = self.next_block_excess_blob_gas()?; + + if self.target_blobs_per_block().is_none() { + Some(eip4844::calc_blob_gasprice(next_block_excess_blob_gas)) + } else { + Some(eip7742::calc_blob_gasprice(next_block_excess_blob_gas)) + } } /// Calculate base fee for next block according to the EIP-1559 spec. @@ -743,6 +830,10 @@ impl BlockHeader for Header { self.requests_hash } + fn target_blobs_per_block(&self) -> Option { + self.target_blobs_per_block + } + fn extra_data(&self) -> &Bytes { &self.extra_data } @@ -833,6 +924,10 @@ impl BlockHeader for alloy_serde::WithOtherFields { fn requests_hash(&self) -> Option { self.inner.requests_hash() } + + fn target_blobs_per_block(&self) -> Option { + self.inner.target_blobs_per_block() + } } /// Bincode-compatibl [`Header`] serde implementation. @@ -886,6 +981,8 @@ pub(crate) mod serde_bincode_compat { parent_beacon_block_root: Option, #[serde(default)] requests_hash: Option, + #[serde(default)] + target_blobs_per_block: Option, extra_data: Cow<'a, Bytes>, } @@ -913,6 +1010,7 @@ pub(crate) mod serde_bincode_compat { parent_beacon_block_root: value.parent_beacon_block_root, requests_hash: value.requests_hash, extra_data: Cow::Borrowed(&value.extra_data), + target_blobs_per_block: value.target_blobs_per_block, } } } @@ -941,6 +1039,7 @@ pub(crate) mod serde_bincode_compat { parent_beacon_block_root: value.parent_beacon_block_root, requests_hash: value.requests_hash, extra_data: value.extra_data.into_owned(), + target_blobs_per_block: value.target_blobs_per_block, } } } diff --git a/crates/eips/src/eip4844/mod.rs b/crates/eips/src/eip4844/mod.rs index 7718d36adc9..698d30b856d 100644 --- a/crates/eips/src/eip4844/mod.rs +++ b/crates/eips/src/eip4844/mod.rs @@ -152,7 +152,7 @@ pub fn calc_blob_gasprice(excess_blob_gas: u64) -> u128 { /// /// This function panics if `denominator` is zero. #[inline] -fn fake_exponential(factor: u128, numerator: u128, denominator: u128) -> u128 { +pub fn fake_exponential(factor: u128, numerator: u128, denominator: u128) -> u128 { assert_ne!(denominator, 0, "attempt to divide by zero"); let mut i = 1; diff --git a/crates/eips/src/eip7742.rs b/crates/eips/src/eip7742.rs new file mode 100644 index 00000000000..5ea6b1405e1 --- /dev/null +++ b/crates/eips/src/eip7742.rs @@ -0,0 +1,65 @@ +//! Contains constants and utility functions for [EIP-7742](https://eips.ethereum.org/EIPS/eip-7742) + +use crate::eip4844::{self, fake_exponential, BLOB_TX_MIN_BLOB_GASPRICE, DATA_GAS_PER_BLOB}; + +/// Controls the update rate of the blob base fee based on `target_blobs_per_block`. +pub const BLOB_BASE_FEE_UPDATE_FRACTION_PER_TARGET_BLOB: u128 = 1112825; + +/// Controls the update rate of the blob base fee based on `target_blobs_per_block`. +pub const EXCESS_BLOB_GAS_NORMALIZATION_TARGET: u64 = 128; + +/// Same as [`eip4844::BLOB_GASPRICE_UPDATE_FRACTION`], but normalized for the target of 128 +/// blobs. +pub const BLOB_BASE_FEE_UPDATE_FRACTION_NORMALIZED: u128 = + BLOB_BASE_FEE_UPDATE_FRACTION_PER_TARGET_BLOB * EXCESS_BLOB_GAS_NORMALIZATION_TARGET as u128; + +/// Calculates the `excess_blob_gas` for the header of the block enabling EIP-7742. +/// +/// Normalizes the parent's excess blob gas as per EIP-7742. +#[inline] +pub const fn calc_excess_blob_gas_at_transition( + parent_excess_blob_gas: u64, + parent_blob_gas_used: u64, + parent_target_blobs_per_block: u64, +) -> u64 { + let normalized_parent_excess_blob_gas = parent_excess_blob_gas + * EXCESS_BLOB_GAS_NORMALIZATION_TARGET + / eip4844::TARGET_BLOBS_PER_BLOCK; + + calc_excess_blob_gas( + normalized_parent_excess_blob_gas, + parent_blob_gas_used, + parent_target_blobs_per_block, + ) +} + +/// Calculates the `excess_blob_gas` from the parent header's `blob_gas_used`, `excess_blob_gas` and +/// `target_blobs_per_block`. +/// +/// Note: this function assumes that the parent block's excess blob gas is normalized as per +/// EIP-7742. +#[inline] +pub const fn calc_excess_blob_gas( + parent_excess_blob_gas: u64, + parent_blob_gas_used: u64, + parent_target_blobs_per_block: u64, +) -> u64 { + let normalized_blob_gas_used = + parent_blob_gas_used * EXCESS_BLOB_GAS_NORMALIZATION_TARGET / parent_target_blobs_per_block; + let normalized_target_blob_gas = DATA_GAS_PER_BLOB * EXCESS_BLOB_GAS_NORMALIZATION_TARGET; + + (parent_excess_blob_gas + normalized_blob_gas_used).saturating_sub(normalized_target_blob_gas) +} + +/// Calculates the blob gas price from the header's excess blob gas field. +/// +/// Similar to [crate::eip4844::calc_blob_gasprice], but adjusts the update rate based on +/// `target_blobs_per_block`. +#[inline] +pub fn calc_blob_gasprice(excess_blob_gas: u64) -> u128 { + fake_exponential( + BLOB_TX_MIN_BLOB_GASPRICE, + excess_blob_gas as u128, + BLOB_BASE_FEE_UPDATE_FRACTION_NORMALIZED, + ) +} diff --git a/crates/eips/src/lib.rs b/crates/eips/src/lib.rs index 2bb4b07e0cf..5ba0bbbe1d5 100644 --- a/crates/eips/src/lib.rs +++ b/crates/eips/src/lib.rs @@ -43,3 +43,5 @@ pub mod eip7251; pub mod eip7685; pub mod eip7702; + +pub mod eip7742; diff --git a/crates/provider/src/fillers/gas.rs b/crates/provider/src/fillers/gas.rs index e39a38e141e..e6d9c173a5e 100644 --- a/crates/provider/src/fillers/gas.rs +++ b/crates/provider/src/fillers/gas.rs @@ -226,12 +226,14 @@ where } } - provider + let latest_block = provider .get_block_by_number(BlockNumberOrTag::Latest, BlockTransactionsKind::Hashes) .await? - .ok_or(RpcError::NullResp)? - .header() - .as_ref() + .ok_or(RpcError::NullResp)?; + + let latest_header = latest_block.header().as_ref(); + + latest_header .next_block_blob_fee() .map(Into::into) .ok_or(RpcError::UnsupportedFeature("eip4844")) diff --git a/crates/rpc-types-beacon/src/payload.rs b/crates/rpc-types-beacon/src/payload.rs index 13bb1fa3099..31f9bd2e10b 100644 --- a/crates/rpc-types-beacon/src/payload.rs +++ b/crates/rpc-types-beacon/src/payload.rs @@ -108,6 +108,12 @@ struct BeaconPayloadAttributes { withdrawals: Option>, #[serde(skip_serializing_if = "Option::is_none")] parent_beacon_block_root: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[serde_as(as = "Option")] + target_blobs_per_block: Option, + #[serde(skip_serializing_if = "Option::is_none")] + #[serde_as(as = "Option")] + max_blobs_per_block: Option, } /// Optimism Payload Attributes @@ -149,6 +155,8 @@ pub mod beacon_api_payload_attributes { suggested_fee_recipient: payload_attributes.suggested_fee_recipient, withdrawals: payload_attributes.withdrawals.clone(), parent_beacon_block_root: payload_attributes.parent_beacon_block_root, + target_blobs_per_block: payload_attributes.target_blobs_per_block, + max_blobs_per_block: payload_attributes.max_blobs_per_block, }; beacon_api_payload_attributes.serialize(serializer) } @@ -165,6 +173,8 @@ pub mod beacon_api_payload_attributes { suggested_fee_recipient: beacon_api_payload_attributes.suggested_fee_recipient, withdrawals: beacon_api_payload_attributes.withdrawals, parent_beacon_block_root: beacon_api_payload_attributes.parent_beacon_block_root, + target_blobs_per_block: beacon_api_payload_attributes.target_blobs_per_block, + max_blobs_per_block: beacon_api_payload_attributes.max_blobs_per_block, }) } } diff --git a/crates/rpc-types-engine/src/lib.rs b/crates/rpc-types-engine/src/lib.rs index d91f05b6979..fcc63e4b120 100644 --- a/crates/rpc-types-engine/src/lib.rs +++ b/crates/rpc-types-engine/src/lib.rs @@ -13,6 +13,8 @@ extern crate alloc; mod cancun; pub use cancun::*; +mod prague; +pub use prague::*; mod sidecar; pub use sidecar::*; diff --git a/crates/rpc-types-engine/src/payload.rs b/crates/rpc-types-engine/src/payload.rs index 58b0d9a71cc..694cc17f1e8 100644 --- a/crates/rpc-types-engine/src/payload.rs +++ b/crates/rpc-types-engine/src/payload.rs @@ -760,6 +760,26 @@ pub struct PayloadAttributes { /// See also #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub parent_beacon_block_root: Option, + /// Target blob count for the block enabled with V4. + #[cfg_attr( + feature = "serde", + serde( + default, + with = "alloy_serde::quantity::opt", + skip_serializing_if = "Option::is_none" + ) + )] + pub target_blobs_per_block: Option, + /// Max blob count for block enabled with V4. + #[cfg_attr( + feature = "serde", + serde( + default, + with = "alloy_serde::quantity::opt", + skip_serializing_if = "Option::is_none" + ) + )] + pub max_blobs_per_block: Option, } /// This structure contains the result of processing a payload or fork choice update. diff --git a/crates/rpc-types-engine/src/prague.rs b/crates/rpc-types-engine/src/prague.rs new file mode 100644 index 00000000000..fc1f119b425 --- /dev/null +++ b/crates/rpc-types-engine/src/prague.rs @@ -0,0 +1,63 @@ +//! Contains types related to the Prague hardfork that will be used by RPC to communicate with the +//! beacon consensus engine. + +use alloy_eips::eip7685::Requests; + +/// Fields introduced in `engine_newPayloadV4` that are not present in the `ExecutionPayload` RPC +/// object. +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct PraguePayloadFields { + /// EIP-7685 requests. + pub requests: Requests, + /// EIP-7742 target number of blobs in the block. + pub target_blobs_per_block: u64, +} + +/// A container type for [PraguePayloadFields] that may or may not be present. +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct MaybePraguePayloadFields { + fields: Option, +} + +impl MaybePraguePayloadFields { + /// Returns a new [`MaybePraguePayloadFields`] with no prague fields. + pub const fn none() -> Self { + Self { fields: None } + } + + /// Returns a new [`MaybePraguePayloadFields`] with the given prague fields. + pub fn into_inner(self) -> Option { + self.fields + } + + /// Returns the requests, if any. + pub fn requests(&self) -> Option<&Requests> { + self.fields.as_ref().map(|fields| &fields.requests) + } + + /// Returns the target blobs per block, if any. + pub fn target_blobs_per_block(&self) -> Option { + self.fields.as_ref().map(|fields| fields.target_blobs_per_block) + } + + /// Returns a reference to the inner fields. + pub const fn as_ref(&self) -> Option<&PraguePayloadFields> { + self.fields.as_ref() + } +} + +impl From for MaybePraguePayloadFields { + #[inline] + fn from(fields: PraguePayloadFields) -> Self { + Self { fields: Some(fields) } + } +} + +impl From> for MaybePraguePayloadFields { + #[inline] + fn from(fields: Option) -> Self { + Self { fields } + } +} diff --git a/crates/rpc-types-engine/src/sidecar.rs b/crates/rpc-types-engine/src/sidecar.rs index a640508bcd8..267f92bf546 100644 --- a/crates/rpc-types-engine/src/sidecar.rs +++ b/crates/rpc-types-engine/src/sidecar.rs @@ -1,6 +1,8 @@ //! Contains helpers for dealing with additional parameters of `newPayload` requests. -use crate::{CancunPayloadFields, MaybeCancunPayloadFields}; +use crate::{ + CancunPayloadFields, MaybeCancunPayloadFields, MaybePraguePayloadFields, PraguePayloadFields, +}; use alloc::vec::Vec; use alloy_eips::eip7685::Requests; use alloy_primitives::B256; @@ -15,23 +17,23 @@ pub struct ExecutionPayloadSidecar { cancun: MaybeCancunPayloadFields, /// The EIP-7685 requests provided as additional request params to `engine_newPayloadV4` that /// are not present in the `ExecutionPayload`. - prague: Option, + prague: MaybePraguePayloadFields, } impl ExecutionPayloadSidecar { /// Returns a new empty instance (pre-cancun, v1, v2) pub const fn none() -> Self { - Self { cancun: MaybeCancunPayloadFields::none(), prague: None } + Self { cancun: MaybeCancunPayloadFields::none(), prague: MaybePraguePayloadFields::none() } } /// Creates a new instance for cancun with the cancun fields for `engine_newPayloadV3` pub fn v3(cancun: CancunPayloadFields) -> Self { - Self { cancun: cancun.into(), prague: None } + Self { cancun: cancun.into(), prague: MaybePraguePayloadFields::none() } } /// Creates a new instance post prague for `engine_newPayloadV4` - pub fn v4(cancun: CancunPayloadFields, requests: Requests) -> Self { - Self { cancun: cancun.into(), prague: Some(requests) } + pub fn v4(cancun: CancunPayloadFields, prague: PraguePayloadFields) -> Self { + Self { cancun: cancun.into(), prague: prague.into() } } /// Returns a reference to the [`CancunPayloadFields`]. @@ -39,6 +41,11 @@ impl ExecutionPayloadSidecar { self.cancun.as_ref() } + /// Returns a reference to the [`PraguePayloadFields`]. + pub const fn prague(&self) -> Option<&PraguePayloadFields> { + self.prague.as_ref() + } + /// Returns the parent beacon block root, if any. pub fn parent_beacon_block_root(&self) -> Option { self.cancun.parent_beacon_block_root() @@ -50,7 +57,12 @@ impl ExecutionPayloadSidecar { } /// Returns the EIP-7685 requests - pub const fn requests(&self) -> Option<&Requests> { - self.prague.as_ref() + pub fn requests(&self) -> Option<&Requests> { + self.prague.requests() + } + + /// Returns the target blobs per block + pub fn target_blobs_per_block(&self) -> Option { + self.prague.target_blobs_per_block() } } diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 94f5b18e0ac..36cf7ed6fe5 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -256,6 +256,10 @@ impl BlockHeader for Header { fn requests_hash(&self) -> Option { self.inner.requests_hash() } + + fn target_blobs_per_block(&self) -> Option { + self.inner.target_blobs_per_block() + } } impl HeaderResponse for Header { @@ -450,6 +454,7 @@ mod tests { excess_blob_gas: None, parent_beacon_block_root: None, requests_hash: None, + target_blobs_per_block: None, }, total_difficulty: Some(U256::from(100000)), size: None, @@ -497,6 +502,7 @@ mod tests { excess_blob_gas: None, parent_beacon_block_root: None, requests_hash: None, + target_blobs_per_block: None, }, size: None, total_difficulty: Some(U256::from(100000)), @@ -542,6 +548,7 @@ mod tests { excess_blob_gas: None, parent_beacon_block_root: None, requests_hash: None, + target_blobs_per_block: None, }, total_difficulty: Some(U256::from(100000)), size: None, @@ -813,6 +820,7 @@ mod tests { excess_blob_gas: None, parent_beacon_block_root: None, requests_hash: None, + target_blobs_per_block: None, }, size: None, total_difficulty: None, @@ -859,6 +867,7 @@ mod tests { excess_blob_gas: None, parent_beacon_block_root: None, requests_hash: None, + target_blobs_per_block: None, }, total_difficulty: None, size: Some(U256::from(505)), @@ -917,6 +926,7 @@ mod tests { excess_blob_gas: None, parent_beacon_block_root: None, requests_hash: None, + target_blobs_per_block: None, }, total_difficulty: Some(U256::from(100000)), size: Some(U256::from(19)),