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

@ -292,10 +292,10 @@ impl StorageInner {
withdrawals_root: withdrawals.map(|w| proofs::calculate_withdrawals_root(w)),
difficulty: U256::from(2),
number: self.best_block + 1,
gas_limit: chain_spec.max_gas_limit,
gas_limit: chain_spec.max_gas_limit.into(),
timestamp,
base_fee_per_gas,
blob_gas_used,
blob_gas_used: blob_gas_used.map(Into::into),
requests_root: requests.map(|r| proofs::calculate_requests_root(&r.0)),
..Default::default()
};
@ -317,8 +317,13 @@ impl StorageInner {
}
_ => (0, 0),
};
header.excess_blob_gas =
Some(calculate_excess_blob_gas(parent_excess_blob_gas, parent_blob_gas_used))
header.excess_blob_gas = Some(
calculate_excess_blob_gas(
parent_excess_blob_gas as u64,
parent_blob_gas_used as u64,
)
.into(),
)
}
header
@ -392,7 +397,7 @@ impl StorageInner {
// now we need to update certain header fields with the results of the execution
header.state_root = db.state_root(hashed_state)?;
header.gas_used = gas_used;
header.gas_used = gas_used.into();
let receipts = execution_outcome.receipts_by_block(header.number);
@ -420,7 +425,7 @@ impl StorageInner {
self.insert_new_block(header.clone(), body);
// set new header with hash that should have been updated by insert_new_block
let new_header = header.seal(self.best_hash);
let new_header = SealedHeader::new(header, self.best_hash);
Ok((new_header, execution_outcome))
}
@ -574,7 +579,7 @@ mod tests {
assert_eq!(header.parent_hash, best_block_hash);
assert_eq!(header.number, best_block_number + 1);
assert_eq!(header.timestamp, timestamp);
assert_eq!(header.gas_limit, chain_spec.max_gas_limit);
assert_eq!(header.gas_limit, chain_spec.max_gas_limit.into());
}
#[test]
@ -668,7 +673,7 @@ mod tests {
withdrawals_root: None,
difficulty: U256::from(2),
number: 1,
gas_limit: chain_spec.max_gas_limit,
gas_limit: chain_spec.max_gas_limit.into(),
timestamp,
base_fee_per_gas: None,
blob_gas_used: Some(0),

View File

@ -106,11 +106,14 @@ struct InvalidHeaderCacheMetrics {
#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::Sealable;
#[test]
fn test_hit_eviction() {
let mut cache = InvalidHeaderCache::new(10);
let header = Header::default().seal_slow();
let sealed = Header::default().seal_slow();
let (header, seal) = sealed.into_parts();
let header = SealedHeader::new(header, seal);
cache.insert(header.clone());
assert_eq!(cache.headers.get(&header.hash()).unwrap().hit_count, 0);

View File

@ -946,7 +946,7 @@ where
.blockchain
.find_block_by_hash(safe_block_hash, BlockSource::Any)?
.ok_or_else(|| ProviderError::UnknownBlockHash(safe_block_hash))?;
self.blockchain.set_safe(safe.header.seal(safe_block_hash));
self.blockchain.set_safe(SealedHeader::new(safe.header, safe_block_hash));
}
Ok(())
}
@ -967,7 +967,8 @@ where
.find_block_by_hash(finalized_block_hash, BlockSource::Any)?
.ok_or_else(|| ProviderError::UnknownBlockHash(finalized_block_hash))?;
self.blockchain.finalize_block(finalized.number)?;
self.blockchain.set_finalized(finalized.header.seal(finalized_block_hash));
self.blockchain
.set_finalized(SealedHeader::new(finalized.header, finalized_block_hash));
}
Ok(())
}

View File

@ -410,6 +410,7 @@ impl<N: ProviderNodeTypes> PipelineState<N> {
#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::Sealable;
use assert_matches::assert_matches;
use futures::poll;
use reth_chainspec::{ChainSpec, ChainSpecBuilder, MAINNET};
@ -598,7 +599,9 @@ mod tests {
header.parent_hash = hash;
header.number += 1;
header.timestamp += 1;
sealed_header = header.seal_slow();
let sealed = header.seal_slow();
let (header, seal) = sealed.into_parts();
sealed_header = SealedHeader::new(header, seal);
client.insert(sealed_header.clone(), body.clone());
}
}
@ -614,12 +617,14 @@ mod tests {
);
let client = TestFullBlockClient::default();
let header = Header {
let sealed = Header {
base_fee_per_gas: Some(7),
gas_limit: chain_spec.max_gas_limit,
gas_limit: chain_spec.max_gas_limit.into(),
..Default::default()
}
.seal_slow();
let (header, seal) = sealed.into_parts();
let header = SealedHeader::new(header, seal);
insert_headers_into_client(&client, header, 0..10);
// set up a pipeline

View File

@ -1,6 +1,10 @@
#![allow(missing_docs)]
use alloy_primitives::{BlockNumber, B256};
use crate::{
engine::hooks::PruneHook, hooks::EngineHooks, BeaconConsensusEngine,
BeaconConsensusEngineError, BeaconConsensusEngineHandle, BeaconForkChoiceUpdateError,
BeaconOnNewPayloadError, EthBeaconConsensus, MIN_BLOCKS_FOR_PIPELINE_RUN,
};
use alloy_primitives::{BlockNumber, Sealable, B256};
use reth_blockchain_tree::{
config::BlockchainTreeConfig, externals::TreeExternals, BlockchainTree, ShareableBlockchainTree,
};
@ -18,6 +22,7 @@ use reth_evm_ethereum::execute::EthExecutorProvider;
use reth_exex_types::FinishedExExHeight;
use reth_network_p2p::{sync::NoopSyncStateUpdater, test_utils::NoopFullBlockClient, BlockClient};
use reth_payload_builder::test_utils::spawn_test_payload_service;
use reth_primitives::SealedHeader;
use reth_provider::{
providers::BlockchainProvider,
test_utils::{create_test_provider_factory_with_chain_spec, MockNodeTypesWithDB},
@ -34,12 +39,6 @@ use reth_tasks::TokioTaskExecutor;
use std::{collections::VecDeque, sync::Arc};
use tokio::sync::{oneshot, watch};
use crate::{
engine::hooks::PruneHook, hooks::EngineHooks, BeaconConsensusEngine,
BeaconConsensusEngineError, BeaconConsensusEngineHandle, BeaconForkChoiceUpdateError,
BeaconOnNewPayloadError, EthBeaconConsensus, MIN_BLOCKS_FOR_PIPELINE_RUN,
};
type DatabaseEnv = TempDatabase<DE>;
type TestBeaconConsensusEngine<Client> = BeaconConsensusEngine<
@ -395,7 +394,9 @@ where
BlockchainTree::new(externals, BlockchainTreeConfig::new(1, 2, 3, 2))
.expect("failed to create tree"),
));
let genesis_block = self.base_config.chain_spec.genesis_header().clone().seal_slow();
let sealed = self.base_config.chain_spec.genesis_header().clone().seal_slow();
let (header, seal) = sealed.into_parts();
let genesis_block = SealedHeader::new(header, seal);
let blockchain_provider =
BlockchainProvider::with_blocks(provider_factory.clone(), tree, genesis_block, None);

View File

@ -16,8 +16,8 @@ use reth_primitives::{
pub const fn validate_header_gas(header: &Header) -> Result<(), ConsensusError> {
if header.gas_used > header.gas_limit {
return Err(ConsensusError::HeaderGasUsedExceedsGasLimit {
gas_used: header.gas_used,
gas_limit: header.gas_limit,
gas_used: header.gas_used as u64,
gas_limit: header.gas_limit as u64,
})
}
Ok(())
@ -65,7 +65,8 @@ pub fn validate_shanghai_withdrawals(block: &SealedBlock) -> Result<(), Consensu
pub fn validate_cancun_gas(block: &SealedBlock) -> Result<(), ConsensusError> {
// Check that the blob gas used in the header matches the sum of the blob gas used by each
// blob tx
let header_blob_gas_used = block.blob_gas_used.ok_or(ConsensusError::BlobGasUsedMissing)?;
let header_blob_gas_used =
block.blob_gas_used.ok_or(ConsensusError::BlobGasUsedMissing)? as u64;
let total_blob_gas = block.blob_gas_used();
if total_blob_gas != header_blob_gas_used {
return Err(ConsensusError::BlobGasUsedDiff(GotExpected {
@ -150,25 +151,25 @@ pub fn validate_4844_header_standalone(header: &Header) -> Result<(), ConsensusE
return Err(ConsensusError::ParentBeaconBlockRootMissing)
}
if blob_gas_used > MAX_DATA_GAS_PER_BLOCK {
if blob_gas_used as u64 > MAX_DATA_GAS_PER_BLOCK {
return Err(ConsensusError::BlobGasUsedExceedsMaxBlobGasPerBlock {
blob_gas_used,
blob_gas_used: blob_gas_used as u64,
max_blob_gas_per_block: MAX_DATA_GAS_PER_BLOCK,
})
}
if blob_gas_used % DATA_GAS_PER_BLOB != 0 {
if blob_gas_used as u64 % DATA_GAS_PER_BLOB != 0 {
return Err(ConsensusError::BlobGasUsedNotMultipleOfBlobGasPerBlob {
blob_gas_used,
blob_gas_used: blob_gas_used as u64,
blob_gas_per_blob: DATA_GAS_PER_BLOB,
})
}
// `excess_blob_gas` must also be a multiple of `DATA_GAS_PER_BLOB`. This will be checked later
// (via `calculate_excess_blob_gas`), but it doesn't hurt to catch the problem sooner.
if excess_blob_gas % DATA_GAS_PER_BLOB != 0 {
if excess_blob_gas as u64 % DATA_GAS_PER_BLOB != 0 {
return Err(ConsensusError::ExcessBlobGasNotMultipleOfBlobGasPerBlob {
excess_blob_gas,
excess_blob_gas: excess_blob_gas as u64,
blob_gas_per_blob: DATA_GAS_PER_BLOB,
})
}
@ -224,7 +225,7 @@ pub fn validate_against_parent_eip1559_base_fee<ChainSpec: EthChainSpec + Ethere
chain_spec: &ChainSpec,
) -> Result<(), ConsensusError> {
if chain_spec.fork(EthereumHardfork::London).active_at_block(header.number) {
let base_fee = header.base_fee_per_gas.ok_or(ConsensusError::BaseFeeMissing)?;
let base_fee = header.base_fee_per_gas.ok_or(ConsensusError::BaseFeeMissing)? as u64;
let expected_base_fee =
if chain_spec.fork(EthereumHardfork::London).transitions_at_block(header.number) {
@ -234,7 +235,7 @@ pub fn validate_against_parent_eip1559_base_fee<ChainSpec: EthChainSpec + Ethere
// them.
parent
.next_block_base_fee(chain_spec.base_fee_params_at_timestamp(header.timestamp))
.ok_or(ConsensusError::BaseFeeMissing)?
.ok_or(ConsensusError::BaseFeeMissing)? as u64
};
if expected_base_fee != base_fee {
return Err(ConsensusError::BaseFeeDiff(GotExpected {
@ -253,7 +254,7 @@ pub const fn validate_against_parent_timestamp(
header: &Header,
parent: &Header,
) -> Result<(), ConsensusError> {
if header.is_timestamp_in_past(parent.timestamp) {
if header.timestamp <= parent.timestamp {
return Err(ConsensusError::TimestampIsInPast {
parent_timestamp: parent.timestamp,
timestamp: header.timestamp,
@ -276,13 +277,14 @@ pub fn validate_against_parent_4844(
// > are evaluated as 0.
//
// This means in the first post-fork block, calculate_excess_blob_gas will return 0.
let parent_blob_gas_used = parent.blob_gas_used.unwrap_or(0);
let parent_excess_blob_gas = parent.excess_blob_gas.unwrap_or(0);
let parent_blob_gas_used = parent.blob_gas_used.unwrap_or(0) as u64;
let parent_excess_blob_gas = parent.excess_blob_gas.unwrap_or(0) as u64;
if header.blob_gas_used.is_none() {
return Err(ConsensusError::BlobGasUsedMissing)
}
let excess_blob_gas = header.excess_blob_gas.ok_or(ConsensusError::ExcessBlobGasMissing)?;
let excess_blob_gas =
header.excess_blob_gas.ok_or(ConsensusError::ExcessBlobGasMissing)? as u64;
let expected_excess_blob_gas =
calculate_excess_blob_gas(parent_excess_blob_gas, parent_blob_gas_used);
@ -300,7 +302,9 @@ pub fn validate_against_parent_4844(
#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::{hex_literal::hex, Address, BlockHash, BlockNumber, Bytes, U256};
use alloy_primitives::{
hex_literal::hex, Address, BlockHash, BlockNumber, Bytes, Sealable, U256,
};
use mockall::mock;
use rand::Rng;
use reth_chainspec::ChainSpecBuilder;
@ -451,7 +455,7 @@ mod tests {
timestamp: 0x635f9657,
extra_data: hex!("")[..].into(),
mix_hash: hex!("0000000000000000000000000000000000000000000000000000000000000000").into(),
nonce: 0x0000000000000000,
nonce: 0x0000000000000000u64.into(),
base_fee_per_gas: 0x28f0001df.into(),
withdrawals_root: None,
blob_gas_used: None,
@ -471,9 +475,12 @@ mod tests {
let ommers = Vec::new();
let body = Vec::new();
let sealed = header.seal_slow();
let (header, seal) = sealed.into_parts();
(
SealedBlock {
header: header.seal_slow(),
header: SealedHeader::new(header, seal),
body,
ommers,
withdrawals: None,
@ -494,12 +501,16 @@ mod tests {
.map(|idx| Withdrawal { index: *idx, ..Default::default() })
.collect(),
);
let sealed = Header {
withdrawals_root: Some(proofs::calculate_withdrawals_root(&withdrawals)),
..Default::default()
}
.seal_slow();
let (header, seal) = sealed.into_parts();
SealedBlock {
header: Header {
withdrawals_root: Some(proofs::calculate_withdrawals_root(&withdrawals)),
..Default::default()
}
.seal_slow(),
header: SealedHeader::new(header, seal),
withdrawals: Some(withdrawals),
..Default::default()
}
@ -531,14 +542,16 @@ mod tests {
// create a tx with 10 blobs
let transaction = mock_blob_tx(1, 10);
let header = Header {
base_fee_per_gas: Some(1337u64),
let sealed = Header {
base_fee_per_gas: Some(1337u128),
withdrawals_root: Some(proofs::calculate_withdrawals_root(&[])),
blob_gas_used: Some(1),
transactions_root: proofs::calculate_transaction_root(&[transaction.clone()]),
..Default::default()
}
.seal_slow();
let (header, seal) = sealed.into_parts();
let header = SealedHeader::new(header, seal);
let body = BlockBody {
transactions: vec![transaction],