primitives: use alloy Header struct (#10691)

This commit is contained in:
Thomas Coratger
2024-09-23 14:53:43 +02:00
committed by GitHub
parent 7529d36515
commit ed1de8996d
85 changed files with 826 additions and 991 deletions

View File

@ -19,7 +19,6 @@ alloy-eips.workspace = true
alloy-genesis.workspace = true
alloy-primitives.workspace = true
alloy-rlp.workspace = true
alloy-rpc-types-eth = { workspace = true, optional = true }
derive_more.workspace = true
revm-primitives = { workspace = true, features = ["serde"] }
@ -60,4 +59,3 @@ arbitrary = [
"dep:proptest",
"dep:proptest-arbitrary-interop",
]
alloy-compat = ["alloy-rpc-types-eth"]

View File

@ -1,47 +0,0 @@
use super::Header;
use alloy_rpc_types_eth::{ConversionError, Header as RpcHeader};
impl TryFrom<RpcHeader> for Header {
type Error = ConversionError;
fn try_from(header: RpcHeader) -> Result<Self, Self::Error> {
Ok(Self {
base_fee_per_gas: header
.base_fee_per_gas
.map(|base_fee_per_gas| {
base_fee_per_gas.try_into().map_err(ConversionError::BaseFeePerGasConversion)
})
.transpose()?,
beneficiary: header.miner,
blob_gas_used: header
.blob_gas_used
.map(|blob_gas_used| {
blob_gas_used.try_into().map_err(ConversionError::BlobGasUsedConversion)
})
.transpose()?,
difficulty: header.difficulty,
excess_blob_gas: header
.excess_blob_gas
.map(|excess_blob_gas| {
excess_blob_gas.try_into().map_err(ConversionError::ExcessBlobGasConversion)
})
.transpose()?,
extra_data: header.extra_data,
gas_limit: header.gas_limit.try_into().map_err(ConversionError::GasLimitConversion)?,
gas_used: header.gas_used.try_into().map_err(ConversionError::GasUsedConversion)?,
logs_bloom: header.logs_bloom,
mix_hash: header.mix_hash.unwrap_or_default(),
nonce: u64::from_be_bytes(header.nonce.unwrap_or_default().0),
number: header.number,
ommers_hash: header.uncles_hash,
parent_beacon_block_root: header.parent_beacon_block_root,
parent_hash: header.parent_hash,
receipts_root: header.receipts_root,
state_root: header.state_root,
timestamp: header.timestamp,
transactions_root: header.transactions_root,
withdrawals_root: header.withdrawals_root,
requests_root: header.requests_root,
})
}
}

View File

@ -7,526 +7,9 @@ pub use error::HeaderError;
#[cfg(any(test, feature = "test-utils", feature = "arbitrary"))]
pub mod test_utils;
use alloy_consensus::constants::{EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH};
use alloy_eips::{
calc_next_block_base_fee, eip1559::BaseFeeParams, merge::ALLOWED_FUTURE_BLOCK_TIME_SECONDS,
BlockNumHash,
};
use alloy_primitives::{keccak256, Address, BlockNumber, Bloom, Bytes, B256, B64, U256};
use alloy_rlp::{length_of_length, Decodable, Encodable};
use bytes::BufMut;
use core::mem;
use reth_codecs::{add_arbitrary_tests, Compact};
use revm_primitives::{calc_blob_gasprice, calc_excess_blob_gas};
use serde::{Deserialize, Serialize};
pub use alloy_consensus::Header;
/// Block header
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Compact)]
#[add_arbitrary_tests(rlp, 25)]
pub struct Header {
/// The Keccak 256-bit hash of the parent
/// blocks header, in its entirety; formally Hp.
pub parent_hash: B256,
/// The Keccak 256-bit hash of the ommers list portion of this block; formally Ho.
pub ommers_hash: B256,
/// The 160-bit address to which all fees collected from the successful mining of this block
/// be transferred; formally Hc.
pub beneficiary: Address,
/// The Keccak 256-bit hash of the root node of the state trie, after all transactions are
/// executed and finalisations applied; formally Hr.
pub state_root: B256,
/// The Keccak 256-bit hash of the root node of the trie structure populated with each
/// transaction in the transactions list portion of the block; formally Ht.
pub transactions_root: B256,
/// The Keccak 256-bit hash of the root node of the trie structure populated with the receipts
/// of each transaction in the transactions list portion of the block; formally He.
pub receipts_root: B256,
/// The Keccak 256-bit hash of the withdrawals list portion of this block.
///
/// See [EIP-4895](https://eips.ethereum.org/EIPS/eip-4895).
pub withdrawals_root: Option<B256>,
/// The Bloom filter composed from indexable information (logger address and log topics)
/// contained in each log entry from the receipt of each transaction in the transactions list;
/// formally Hb.
pub logs_bloom: Bloom,
/// A scalar value corresponding to the difficulty level of this block. This can be calculated
/// from the previous blocks difficulty level and the timestamp; formally Hd.
pub difficulty: U256,
/// A scalar value equal to the number of ancestor blocks. The genesis block has a number of
/// zero; formally Hi.
pub number: BlockNumber,
/// A scalar value equal to the current limit of gas expenditure per block; formally Hl.
pub gas_limit: u64,
/// A scalar value equal to the total gas used in transactions in this block; formally Hg.
pub gas_used: u64,
/// A scalar value equal to the reasonable output of Unixs time() at this blocks inception;
/// formally Hs.
pub timestamp: u64,
/// A 256-bit hash which, combined with the
/// nonce, proves that a sufficient amount of computation has been carried out on this block;
/// formally Hm.
pub mix_hash: B256,
/// A 64-bit value which, combined with the mixhash, proves that a sufficient amount of
/// computation has been carried out on this block; formally Hn.
pub nonce: u64,
/// A scalar representing EIP1559 base fee which can move up or down each block according
/// to a formula which is a function of gas used in parent block and gas target
/// (block gas limit divided by elasticity multiplier) of parent block.
/// The algorithm results in the base fee per gas increasing when blocks are
/// above the gas target, and decreasing when blocks are below the gas target. The base fee per
/// gas is burned.
pub base_fee_per_gas: Option<u64>,
/// The total amount of blob gas consumed by the transactions within the block, added in
/// EIP-4844.
pub blob_gas_used: Option<u64>,
/// A running total of blob gas consumed in excess of the target, prior to the block. Blocks
/// with above-target blob gas consumption increase this value, blocks with below-target blob
/// gas consumption decrease it (bounded at 0). This was added in EIP-4844.
pub excess_blob_gas: Option<u64>,
/// The hash of the parent beacon block's root is included in execution blocks, as proposed by
/// EIP-4788.
///
/// This enables trust-minimized access to consensus state, supporting staking pools, bridges,
/// and more.
///
/// The beacon roots contract handles root storage, enhancing Ethereum's functionalities.
pub parent_beacon_block_root: Option<B256>,
/// The Keccak 256-bit hash of the root node of the trie structure populated with each
/// [EIP-7685] request in the block body.
///
/// [EIP-7685]: https://eips.ethereum.org/EIPS/eip-7685
pub requests_root: Option<B256>,
/// An arbitrary byte array containing data relevant to this block. This must be 32 bytes or
/// fewer; formally Hx.
pub extra_data: Bytes,
}
impl AsRef<Self> for Header {
fn as_ref(&self) -> &Self {
self
}
}
impl Default for Header {
fn default() -> Self {
Self {
parent_hash: Default::default(),
ommers_hash: EMPTY_OMMER_ROOT_HASH,
beneficiary: Default::default(),
state_root: EMPTY_ROOT_HASH,
transactions_root: EMPTY_ROOT_HASH,
receipts_root: EMPTY_ROOT_HASH,
logs_bloom: Default::default(),
difficulty: Default::default(),
number: 0,
gas_limit: 0,
gas_used: 0,
timestamp: 0,
extra_data: Default::default(),
mix_hash: Default::default(),
nonce: 0,
base_fee_per_gas: None,
withdrawals_root: None,
blob_gas_used: None,
excess_blob_gas: None,
parent_beacon_block_root: None,
requests_root: None,
}
}
}
impl Header {
/// Checks if the block's difficulty is set to zero, indicating a Proof-of-Stake header.
///
/// This function is linked to EIP-3675, proposing the consensus upgrade to Proof-of-Stake:
/// [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#replacing-difficulty-with-0)
///
/// Verifies whether, as per the EIP, the block's difficulty is updated to zero,
/// signifying the transition to a Proof-of-Stake mechanism.
///
/// Returns `true` if the block's difficulty matches the constant zero set by the EIP.
pub fn is_zero_difficulty(&self) -> bool {
self.difficulty.is_zero()
}
/// Performs a sanity check on the extradata field of the header.
///
/// # Errors
///
/// Returns an error if the extradata size is larger than 100 KB.
pub fn ensure_extradata_valid(&self) -> Result<(), HeaderError> {
if self.extra_data.len() > 100 * 1024 {
return Err(HeaderError::LargeExtraData)
}
Ok(())
}
/// Performs a sanity check on the block difficulty field of the header.
///
/// # Errors
///
/// Returns an error if the block difficulty exceeds 80 bits.
pub fn ensure_difficulty_valid(&self) -> Result<(), HeaderError> {
if self.difficulty.bit_len() > 80 {
return Err(HeaderError::LargeDifficulty)
}
Ok(())
}
/// Performs combined sanity checks on multiple header fields.
///
/// This method combines checks for block difficulty and extradata sizes.
///
/// # Errors
///
/// Returns an error if either the block difficulty exceeds 80 bits
/// or if the extradata size is larger than 100 KB.
pub fn ensure_well_formed(&self) -> Result<(), HeaderError> {
self.ensure_difficulty_valid()?;
self.ensure_extradata_valid()?;
Ok(())
}
/// Checks if the block's timestamp is in the past compared to the parent block's timestamp.
///
/// Note: This check is relevant only pre-merge.
pub const fn is_timestamp_in_past(&self, parent_timestamp: u64) -> bool {
self.timestamp <= parent_timestamp
}
/// Checks if the block's timestamp is in the future based on the present timestamp.
///
/// Clock can drift but this can be consensus issue.
///
/// Note: This check is relevant only pre-merge.
pub const fn exceeds_allowed_future_timestamp(&self, present_timestamp: u64) -> bool {
self.timestamp > present_timestamp + ALLOWED_FUTURE_BLOCK_TIME_SECONDS
}
/// Returns the parent block's number and hash
pub const fn parent_num_hash(&self) -> BlockNumHash {
BlockNumHash { number: self.number.saturating_sub(1), hash: self.parent_hash }
}
/// Heavy function that will calculate hash of data and will *not* save the change to metadata.
/// Use [`Header::seal`], [`SealedHeader`] and unlock if you need hash to be persistent.
pub fn hash_slow(&self) -> B256 {
keccak256(alloy_rlp::encode(self))
}
/// Checks if the header is empty - has no transactions and no ommers
pub fn is_empty(&self) -> bool {
self.transaction_root_is_empty() &&
self.ommers_hash_is_empty() &&
self.withdrawals_root.map_or(true, |root| root == EMPTY_ROOT_HASH)
}
/// Check if the ommers hash equals to empty hash list.
pub fn ommers_hash_is_empty(&self) -> bool {
self.ommers_hash == EMPTY_OMMER_ROOT_HASH
}
/// Check if the transaction root equals to empty root.
pub fn transaction_root_is_empty(&self) -> bool {
self.transactions_root == EMPTY_ROOT_HASH
}
/// Returns the blob fee for _this_ block according to the EIP-4844 spec.
///
/// Returns `None` if `excess_blob_gas` is None
pub fn blob_fee(&self) -> Option<u128> {
self.excess_blob_gas.map(calc_blob_gasprice)
}
/// 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<u128> {
self.next_block_excess_blob_gas().map(calc_blob_gasprice)
}
/// Calculate base fee for next block according to the EIP-1559 spec.
///
/// Returns a `None` if no base fee is set, no EIP-1559 support
pub fn next_block_base_fee(&self, base_fee_params: BaseFeeParams) -> Option<u64> {
Some(calc_next_block_base_fee(
self.gas_used as u128,
self.gas_limit as u128,
self.base_fee_per_gas? as u128,
base_fee_params,
) as u64)
}
/// 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<u64> {
Some(calc_excess_blob_gas(self.excess_blob_gas?, self.blob_gas_used?))
}
/// Seal the header with a known hash.
///
/// WARNING: This method does not perform validation whether the hash is correct.
#[inline]
pub const fn seal(self, hash: B256) -> SealedHeader {
SealedHeader::new(self, hash)
}
/// Calculate hash and seal the Header so that it can't be changed.
#[inline]
pub fn seal_slow(self) -> SealedHeader {
let hash = self.hash_slow();
self.seal(hash)
}
/// Calculate a heuristic for the in-memory size of the [Header].
#[inline]
pub fn size(&self) -> usize {
mem::size_of::<B256>() + // parent hash
mem::size_of::<B256>() + // ommers hash
mem::size_of::<Address>() + // beneficiary
mem::size_of::<B256>() + // state root
mem::size_of::<B256>() + // transactions root
mem::size_of::<B256>() + // receipts root
mem::size_of::<Option<B256>>() + // withdrawals root
mem::size_of::<Bloom>() + // logs bloom
mem::size_of::<U256>() + // difficulty
mem::size_of::<BlockNumber>() + // number
mem::size_of::<u64>() + // gas limit
mem::size_of::<u64>() + // gas used
mem::size_of::<u64>() + // timestamp
mem::size_of::<B256>() + // mix hash
mem::size_of::<u64>() + // nonce
mem::size_of::<Option<u64>>() + // base fee per gas
mem::size_of::<Option<u64>>() + // blob gas used
mem::size_of::<Option<u64>>() + // excess blob gas
mem::size_of::<Option<B256>>() + // parent beacon block root
self.extra_data.len() // extra data
}
fn header_payload_length(&self) -> usize {
let mut length = 0;
length += self.parent_hash.length(); // Hash of the previous block.
length += self.ommers_hash.length(); // Hash of uncle blocks.
length += self.beneficiary.length(); // Address that receives rewards.
length += self.state_root.length(); // Root hash of the state object.
length += self.transactions_root.length(); // Root hash of transactions in the block.
length += self.receipts_root.length(); // Hash of transaction receipts.
length += self.logs_bloom.length(); // Data structure containing event logs.
length += self.difficulty.length(); // Difficulty value of the block.
length += U256::from(self.number).length(); // Block number.
length += U256::from(self.gas_limit).length(); // Maximum gas allowed.
length += U256::from(self.gas_used).length(); // Actual gas used.
length += self.timestamp.length(); // Block timestamp.
length += self.extra_data.length(); // Additional arbitrary data.
length += self.mix_hash.length(); // Hash used for mining.
length += B64::new(self.nonce.to_be_bytes()).length(); // Nonce for mining.
if let Some(base_fee) = self.base_fee_per_gas {
// Adding base fee length if it exists.
length += U256::from(base_fee).length();
}
if let Some(root) = self.withdrawals_root {
// Adding withdrawals_root length if it exists.
length += root.length();
}
if let Some(blob_gas_used) = self.blob_gas_used {
// Adding blob_gas_used length if it exists.
length += U256::from(blob_gas_used).length();
}
if let Some(excess_blob_gas) = self.excess_blob_gas {
// Adding excess_blob_gas length if it exists.
length += U256::from(excess_blob_gas).length();
}
if let Some(parent_beacon_block_root) = self.parent_beacon_block_root {
length += parent_beacon_block_root.length();
}
if let Some(requests_root) = self.requests_root {
length += requests_root.length();
}
length
}
}
impl Encodable for Header {
fn encode(&self, out: &mut dyn BufMut) {
// Create a header indicating the encoded content is a list with the payload length computed
// from the header's payload calculation function.
let list_header =
alloy_rlp::Header { list: true, payload_length: self.header_payload_length() };
list_header.encode(out);
// Encode each header field sequentially
self.parent_hash.encode(out); // Encode parent hash.
self.ommers_hash.encode(out); // Encode ommer's hash.
self.beneficiary.encode(out); // Encode beneficiary.
self.state_root.encode(out); // Encode state root.
self.transactions_root.encode(out); // Encode transactions root.
self.receipts_root.encode(out); // Encode receipts root.
self.logs_bloom.encode(out); // Encode logs bloom.
self.difficulty.encode(out); // Encode difficulty.
U256::from(self.number).encode(out); // Encode block number.
U256::from(self.gas_limit).encode(out); // Encode gas limit.
U256::from(self.gas_used).encode(out); // Encode gas used.
self.timestamp.encode(out); // Encode timestamp.
self.extra_data.encode(out); // Encode extra data.
self.mix_hash.encode(out); // Encode mix hash.
B64::new(self.nonce.to_be_bytes()).encode(out); // Encode nonce.
// Encode base fee.
if let Some(ref base_fee) = self.base_fee_per_gas {
U256::from(*base_fee).encode(out);
}
// Encode withdrawals root.
if let Some(ref root) = self.withdrawals_root {
root.encode(out);
}
// Encode blob gas used.
if let Some(ref blob_gas_used) = self.blob_gas_used {
U256::from(*blob_gas_used).encode(out);
}
// Encode excess blob gas.
if let Some(ref excess_blob_gas) = self.excess_blob_gas {
U256::from(*excess_blob_gas).encode(out);
}
// Encode parent beacon block root.
if let Some(ref parent_beacon_block_root) = self.parent_beacon_block_root {
parent_beacon_block_root.encode(out);
}
// Encode EIP-7685 requests root
if let Some(ref requests_root) = self.requests_root {
requests_root.encode(out);
}
}
fn length(&self) -> usize {
let mut length = 0;
length += self.header_payload_length();
length += length_of_length(length);
length
}
}
impl Decodable for Header {
fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
let rlp_head = alloy_rlp::Header::decode(buf)?;
if !rlp_head.list {
return Err(alloy_rlp::Error::UnexpectedString)
}
let started_len = buf.len();
let mut this = Self {
parent_hash: Decodable::decode(buf)?,
ommers_hash: Decodable::decode(buf)?,
beneficiary: Decodable::decode(buf)?,
state_root: Decodable::decode(buf)?,
transactions_root: Decodable::decode(buf)?,
receipts_root: Decodable::decode(buf)?,
logs_bloom: Decodable::decode(buf)?,
difficulty: Decodable::decode(buf)?,
number: u64::decode(buf)?,
gas_limit: u64::decode(buf)?,
gas_used: u64::decode(buf)?,
timestamp: Decodable::decode(buf)?,
extra_data: Decodable::decode(buf)?,
mix_hash: Decodable::decode(buf)?,
nonce: u64::from_be_bytes(B64::decode(buf)?.0),
base_fee_per_gas: None,
withdrawals_root: None,
blob_gas_used: None,
excess_blob_gas: None,
parent_beacon_block_root: None,
requests_root: None,
};
if started_len - buf.len() < rlp_head.payload_length {
this.base_fee_per_gas = Some(u64::decode(buf)?);
}
// Withdrawals root for post-shanghai headers
if started_len - buf.len() < rlp_head.payload_length {
this.withdrawals_root = Some(Decodable::decode(buf)?);
}
// Blob gas used and excess blob gas for post-cancun headers
if started_len - buf.len() < rlp_head.payload_length {
this.blob_gas_used = Some(u64::decode(buf)?);
}
if started_len - buf.len() < rlp_head.payload_length {
this.excess_blob_gas = Some(u64::decode(buf)?);
}
// Decode parent beacon block root.
if started_len - buf.len() < rlp_head.payload_length {
this.parent_beacon_block_root = Some(B256::decode(buf)?);
}
// Decode requests root.
if started_len - buf.len() < rlp_head.payload_length {
this.requests_root = Some(B256::decode(buf)?);
}
let consumed = started_len - buf.len();
if consumed != rlp_head.payload_length {
return Err(alloy_rlp::Error::ListLengthMismatch {
expected: rlp_head.payload_length,
got: consumed,
})
}
Ok(this)
}
}
#[cfg(any(test, feature = "test-utils", feature = "arbitrary"))]
impl<'a> arbitrary::Arbitrary<'a> for Header {
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
// Generate an arbitrary header, passing it to the generate_valid_header function to make
// sure it is valid _with respect to hardforks only_.
let base = Self {
parent_hash: u.arbitrary()?,
ommers_hash: u.arbitrary()?,
beneficiary: u.arbitrary()?,
state_root: u.arbitrary()?,
transactions_root: u.arbitrary()?,
receipts_root: u.arbitrary()?,
logs_bloom: u.arbitrary()?,
difficulty: u.arbitrary()?,
number: u.arbitrary()?,
gas_limit: u.arbitrary()?,
gas_used: u.arbitrary()?,
timestamp: u.arbitrary()?,
extra_data: u.arbitrary()?,
mix_hash: u.arbitrary()?,
nonce: u.arbitrary()?,
base_fee_per_gas: u.arbitrary()?,
blob_gas_used: u.arbitrary()?,
excess_blob_gas: u.arbitrary()?,
parent_beacon_block_root: u.arbitrary()?,
requests_root: u.arbitrary()?,
withdrawals_root: u.arbitrary()?,
};
Ok(test_utils::generate_valid_header(
base,
u.arbitrary()?,
u.arbitrary()?,
u.arbitrary()?,
u.arbitrary()?,
))
}
}
use alloy_primitives::{Address, BlockNumber, B256, U256};
/// Trait for extracting specific Ethereum block data from a header
pub trait BlockHeader {
@ -569,7 +52,7 @@ impl BlockHeader for Header {
}
fn gas_limit(&self) -> u64 {
self.gas_limit
self.gas_limit as u64
}
fn timestamp(&self) -> u64 {
@ -581,10 +64,10 @@ impl BlockHeader for Header {
}
fn base_fee_per_gas(&self) -> Option<u64> {
self.base_fee_per_gas
self.base_fee_per_gas.map(|base_fee| base_fee as u64)
}
fn excess_blob_gas(&self) -> Option<u64> {
self.excess_blob_gas
self.excess_blob_gas.map(|excess_blob_gas| excess_blob_gas as u64)
}
}

View File

@ -1,6 +1,6 @@
use super::Header;
use alloy_eips::BlockNumHash;
use alloy_primitives::{keccak256, BlockHash};
use alloy_primitives::{keccak256, BlockHash, Sealable};
#[cfg(any(test, feature = "test-utils"))]
use alloy_primitives::{BlockNumber, B256, U256};
use alloy_rlp::{Decodable, Encodable};
@ -66,7 +66,9 @@ impl SealedHeader {
impl Default for SealedHeader {
fn default() -> Self {
Header::default().seal_slow()
let sealed = Header::default().seal_slow();
let (header, hash) = sealed.into_parts();
Self { header, hash }
}
}
@ -131,6 +133,18 @@ impl SealedHeader {
#[cfg(any(test, feature = "arbitrary"))]
impl<'a> arbitrary::Arbitrary<'a> for SealedHeader {
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
Ok(Header::arbitrary(u)?.seal_slow())
let mut header = Header::arbitrary(u)?;
header.gas_limit = (header.gas_limit as u64).into();
header.gas_used = (header.gas_used as u64).into();
header.base_fee_per_gas =
header.base_fee_per_gas.map(|base_fee_per_gas| (base_fee_per_gas as u64).into());
header.blob_gas_used =
header.blob_gas_used.map(|blob_gas_used| (blob_gas_used as u64).into());
header.excess_blob_gas =
header.excess_blob_gas.map(|excess_blob_gas| (excess_blob_gas as u64).into());
let sealed = header.seal_slow();
let (header, seal) = sealed.into_parts();
Ok(Self::new(header, seal))
}
}

View File

@ -27,8 +27,8 @@ pub const fn generate_valid_header(
// Set fields based on EIP-4844 being active
if eip_4844_active {
header.blob_gas_used = Some(blob_gas_used);
header.excess_blob_gas = Some(excess_blob_gas);
header.blob_gas_used = Some(blob_gas_used as u128);
header.excess_blob_gas = Some(excess_blob_gas as u128);
header.parent_beacon_block_root = Some(parent_beacon_block_root);
} else {
header.blob_gas_used = None;

View File

@ -12,9 +12,6 @@
#[macro_use]
extern crate alloc;
#[cfg(feature = "alloy-compat")]
mod alloy_compat;
/// Common constants.
pub mod constants;
pub use constants::gas_units::{format_gas, format_gas_throughput};