Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion crates/era-utils/src/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use reth_era::{
},
};
use reth_fs_util as fs;
use reth_provider::StaticFileProviderFactory;
use reth_storage_api::{BlockNumReader, BlockReader, HeaderProvider};
use std::{
path::PathBuf,
Expand Down Expand Up @@ -80,7 +81,7 @@ impl ExportConfig {
/// for a given number of blocks then writes them to disk.
pub fn export<P>(provider: &P, config: &ExportConfig) -> Result<Vec<PathBuf>>
where
P: BlockReader,
P: BlockReader + StaticFileProviderFactory,
{
config.validate()?;
info!(
Expand Down Expand Up @@ -115,6 +116,7 @@ where
let mut total_difficulty = if config.first_block_number > 0 {
let prev_block_number = config.first_block_number - 1;
provider
.static_file_provider()
.header_td_by_number(prev_block_number)?
.ok_or_else(|| eyre!("Total difficulty not found for block {prev_block_number}"))?
} else {
Expand Down
8 changes: 4 additions & 4 deletions crates/era-utils/src/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ use reth_etl::Collector;
use reth_fs_util as fs;
use reth_primitives_traits::{Block, FullBlockBody, FullBlockHeader, NodePrimitives};
use reth_provider::{
providers::StaticFileProviderRWRefMut, BlockWriter, ProviderError, StaticFileProviderFactory,
providers::StaticFileProviderRWRefMut, BlockWriter, StaticFileProviderFactory,
StaticFileSegment, StaticFileWriter,
};
use reth_stages_types::{
CheckpointBlockRange, EntitiesCheckpoint, HeadersCheckpoint, StageCheckpoint, StageId,
};
use reth_storage_api::{
errors::ProviderResult, DBProvider, DatabaseProviderFactory, HeaderProvider,
NodePrimitivesProvider, StageCheckpointWriter,
errors::ProviderResult, DBProvider, DatabaseProviderFactory, NodePrimitivesProvider,
StageCheckpointWriter,
};
use std::{
collections::Bound,
Expand Down Expand Up @@ -85,7 +85,7 @@ where
// Find the latest total difficulty
let mut td = static_file_provider
.header_td_by_number(height)?
.ok_or(ProviderError::TotalDifficultyNotFound(height))?;
.ok_or_else(|| eyre::eyre!("Total difficulty not found for block {height}"))?;

while let Some(meta) = rx.recv()? {
let from = height;
Expand Down
10 changes: 2 additions & 8 deletions crates/node/core/src/node_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
};
use alloy_consensus::BlockHeader;
use alloy_eips::BlockHashOrNumber;
use alloy_primitives::{BlockNumber, B256};
use alloy_primitives::{BlockNumber, B256, U256};
use eyre::eyre;
use reth_chainspec::{ChainSpec, EthChainSpec, MAINNET};
use reth_config::config::PruneConfig;
Expand Down Expand Up @@ -330,12 +330,6 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
.header_by_number(head)?
.expect("the header for the latest block is missing, database is corrupt");

let total_difficulty = provider
.header_td_by_number(head)?
// total difficulty is effectively deprecated, but still required in some places, e.g.
// p2p
.unwrap_or_default();

let hash = provider
.block_hash(head)?
.expect("the hash for the latest block is missing, database is corrupt");
Expand All @@ -344,7 +338,7 @@ impl<ChainSpec> NodeConfig<ChainSpec> {
number: head,
hash,
difficulty: header.difficulty(),
total_difficulty,
total_difficulty: U256::ZERO,
Copy link
Collaborator Author

@joshieDo joshieDo Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

im guessing so, but is this okay?

Copy link
Member

@Rjected Rjected Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be fine, in p2p this is deprecated as of eth/69 and the node builder only uses the Head to get the timestamp

timestamp: header.timestamp(),
})
}
Expand Down
1 change: 0 additions & 1 deletion crates/rpc/rpc-eth-types/src/error/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,6 @@ impl From<reth_errors::ProviderError> for EthApiError {
}
ProviderError::BestBlockNotFound => Self::HeaderNotFound(BlockId::latest()),
ProviderError::BlockNumberForTransactionIndexNotFound => Self::UnknownBlockOrTxIndex,
ProviderError::TotalDifficultyNotFound(num) => Self::HeaderNotFound(num.into()),
ProviderError::FinalizedBlockNotFound => Self::HeaderNotFound(BlockId::finalized()),
ProviderError::SafeBlockNotFound => Self::HeaderNotFound(BlockId::safe()),
err => Self::Internal(err.into()),
Expand Down
15 changes: 9 additions & 6 deletions crates/stages/stages/src/stages/era.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ use reth_era_utils as era;
use reth_etl::Collector;
use reth_primitives_traits::{FullBlockBody, FullBlockHeader, NodePrimitives};
use reth_provider::{
BlockReader, BlockWriter, DBProvider, HeaderProvider, StageCheckpointWriter,
BlockReader, BlockWriter, DBProvider, ProviderError, StageCheckpointWriter,
StaticFileProviderFactory, StaticFileWriter,
};
use reth_stages_api::{ExecInput, ExecOutput, Stage, StageError, UnwindInput, UnwindOutput};
use reth_static_file_types::StaticFileSegment;
use reth_storage_errors::ProviderError;
use std::{
fmt::{Debug, Formatter},
iter,
Expand Down Expand Up @@ -179,7 +178,7 @@ where
// Find the latest total difficulty
let mut td = static_file_provider
.header_td_by_number(last_header_number)?
.ok_or(ProviderError::TotalDifficultyNotFound(last_header_number))?;
.ok_or(ProviderError::HeaderNotFound(last_header_number.into()))?;

// Although headers were downloaded in reverse order, the collector iterates it in
// ascending order
Expand Down Expand Up @@ -336,7 +335,7 @@ mod tests {
};
use reth_ethereum_primitives::TransactionSigned;
use reth_primitives_traits::{SealedBlock, SealedHeader};
use reth_provider::{BlockNumReader, TransactionsProvider};
use reth_provider::{BlockNumReader, HeaderProvider, TransactionsProvider};
use reth_testing_utils::generators::{
random_block_range, random_signed_tx, BlockRangeParams,
};
Expand Down Expand Up @@ -447,7 +446,8 @@ mod tests {
match output {
Some(output) if output.checkpoint.block_number > initial_checkpoint => {
let provider = self.db.factory.provider()?;
let mut td = provider
let static_file_provider = self.db.factory.static_file_provider();
let mut td = static_file_provider
.header_td_by_number(initial_checkpoint.saturating_sub(1))?
.unwrap_or_default();

Expand All @@ -472,7 +472,10 @@ mod tests {

// validate the header total difficulty
td += header.difficulty;
assert_eq!(provider.header_td_by_number(block_num)?, Some(td));
assert_eq!(
static_file_provider.header_td_by_number(block_num)?,
Some(td)
);
}

self.validate_db_blocks(
Expand Down
23 changes: 14 additions & 9 deletions crates/stages/stages/src/stages/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,14 @@ use reth_network_p2p::headers::{
};
use reth_primitives_traits::{serde_bincode_compat, FullBlockHeader, NodePrimitives, SealedHeader};
use reth_provider::{
providers::StaticFileWriter, BlockHashReader, DBProvider, HeaderProvider,
HeaderSyncGapProvider, StaticFileProviderFactory,
providers::StaticFileWriter, BlockHashReader, DBProvider, HeaderSyncGapProvider, ProviderError,
StaticFileProviderFactory,
};
use reth_stages_api::{
CheckpointBlockRange, EntitiesCheckpoint, ExecInput, ExecOutput, HeadersCheckpoint, Stage,
StageCheckpoint, StageError, StageId, UnwindInput, UnwindOutput,
};
use reth_static_file_types::StaticFileSegment;
use reth_storage_errors::provider::ProviderError;
use std::task::{ready, Context, Poll};

use tokio::sync::watch;
Expand Down Expand Up @@ -110,7 +109,7 @@ where
// Find the latest total difficulty
let mut td = static_file_provider
.header_td_by_number(last_header_number)?
.ok_or(ProviderError::TotalDifficultyNotFound(last_header_number))?;
.ok_or(ProviderError::HeaderNotFound(last_header_number.into()))?;

// Although headers were downloaded in reverse order, the collector iterates it in ascending
// order
Expand Down Expand Up @@ -415,7 +414,7 @@ mod tests {
ReverseHeadersDownloader, ReverseHeadersDownloaderBuilder,
};
use reth_network_p2p::test_utils::{TestHeaderDownloader, TestHeadersClient};
use reth_provider::{test_utils::MockNodeTypesWithDB, BlockNumReader};
use reth_provider::{test_utils::MockNodeTypesWithDB, BlockNumReader, HeaderProvider};
use tokio::sync::watch;

pub(crate) struct HeadersTestRunner<D: HeaderDownloader> {
Expand Down Expand Up @@ -493,7 +492,8 @@ mod tests {
match output {
Some(output) if output.checkpoint.block_number > initial_checkpoint => {
let provider = self.db.factory.provider()?;
let mut td = provider
let static_file_provider = self.db.factory.static_file_provider();
let mut td = static_file_provider
.header_td_by_number(initial_checkpoint.saturating_sub(1))?
.unwrap_or_default();

Expand All @@ -512,7 +512,10 @@ mod tests {

// validate the header total difficulty
td += header.difficulty;
assert_eq!(provider.header_td_by_number(block_num)?, Some(td));
assert_eq!(
static_file_provider.header_td_by_number(block_num)?,
Some(td)
);
}
}
_ => self.check_no_header_entry_above(initial_checkpoint)?,
Expand Down Expand Up @@ -639,8 +642,10 @@ mod tests {
header.difficulty()
} else {
let parent_block_number = header.number() - 1;
let parent_ttd =
provider.header_td_by_number(parent_block_number).unwrap().unwrap_or_default();
let parent_ttd = static_file_provider
.header_td_by_number(parent_block_number)
.unwrap()
.unwrap_or_default();
parent_ttd + header.difficulty()
};

Expand Down
3 changes: 0 additions & 3 deletions crates/storage/errors/src/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ pub enum ProviderError {
/// The account address.
address: Address,
},
/// The total difficulty for a block is missing.
#[error("total difficulty not found for block #{_0}")]
TotalDifficultyNotFound(BlockNumber),
/// When required header related data was not found but was required.
#[error("no header found for {_0:?}")]
HeaderNotFound(BlockHashOrNumber),
Expand Down
22 changes: 1 addition & 21 deletions crates/storage/provider/src/providers/blockchain_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{
};
use alloy_consensus::transaction::TransactionMeta;
use alloy_eips::{BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag};
use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256};
use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256};
use alloy_rpc_types_engine::ForkchoiceState;
use reth_chain_state::{
BlockState, CanonicalInMemoryState, ForkChoiceNotifications, ForkChoiceSubscriptions,
Expand Down Expand Up @@ -176,14 +176,6 @@ impl<N: ProviderNodeTypes> HeaderProvider for BlockchainProvider<N> {
self.consistent_provider()?.header_by_number(num)
}

fn header_td(&self, hash: BlockHash) -> ProviderResult<Option<U256>> {
self.consistent_provider()?.header_td(hash)
}

fn header_td_by_number(&self, number: BlockNumber) -> ProviderResult<Option<U256>> {
self.consistent_provider()?.header_td_by_number(number)
}

fn headers_range(
&self,
range: impl RangeBounds<BlockNumber>,
Expand Down Expand Up @@ -1280,24 +1272,12 @@ mod tests {
BlockRangeParams::default(),
)?;

let database_block = database_blocks.first().unwrap().clone();
let in_memory_block = in_memory_blocks.last().unwrap().clone();
// make sure that the finalized block is on db
let finalized_block = database_blocks.get(database_blocks.len() - 3).unwrap();
provider.set_finalized(finalized_block.clone_sealed_header());

let blocks = [database_blocks, in_memory_blocks].concat();

assert_eq!(
provider.header_td_by_number(database_block.number)?,
Some(database_block.difficulty)
);

assert_eq!(
provider.header_td_by_number(in_memory_block.number)?,
Some(in_memory_block.difficulty)
);

assert_eq!(
provider.sealed_headers_while(0..=10, |header| header.number <= 8)?,
blocks
Expand Down
33 changes: 1 addition & 32 deletions crates/storage/provider/src/providers/consistent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use alloy_eips::{
};
use alloy_primitives::{
map::{hash_map, HashMap},
Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256,
Address, BlockHash, BlockNumber, TxHash, TxNumber, B256,
};
use reth_chain_state::{BlockState, CanonicalInMemoryState, MemoryOverlayStateProviderRef};
use reth_chainspec::ChainInfo;
Expand Down Expand Up @@ -663,37 +663,6 @@ impl<N: ProviderNodeTypes> HeaderProvider for ConsistentProvider<N> {
)
}

fn header_td(&self, hash: BlockHash) -> ProviderResult<Option<U256>> {
if let Some(num) = self.block_number(hash)? {
self.header_td_by_number(num)
} else {
Ok(None)
}
}

fn header_td_by_number(&self, number: BlockNumber) -> ProviderResult<Option<U256>> {
let number = if self.head_block.as_ref().map(|b| b.block_on_chain(number.into())).is_some()
{
// If the block exists in memory, we should return a TD for it.
//
// The canonical in memory state should only store post-merge blocks. Post-merge blocks
// have zero difficulty. This means we can use the total difficulty for the last
// finalized block number if present (so that we are not affected by reorgs), if not the
// last number in the database will be used.
if let Some(last_finalized_num_hash) =
self.canonical_in_memory_state.get_finalized_num_hash()
{
last_finalized_num_hash.number
} else {
self.last_block_number()?
}
} else {
// Otherwise, return what we have on disk for the input block
number
};
self.storage_provider.header_td_by_number(number)
}

fn headers_range(
&self,
range: impl RangeBounds<BlockNumber>,
Expand Down
10 changes: 1 addition & 9 deletions crates/storage/provider/src/providers/database/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::{
};
use alloy_consensus::transaction::TransactionMeta;
use alloy_eips::BlockHashOrNumber;
use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256};
use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash, TxNumber, B256};
use core::fmt;
use reth_chainspec::ChainInfo;
use reth_db::{init_db, mdbx::DatabaseArguments, DatabaseEnv};
Expand Down Expand Up @@ -247,14 +247,6 @@ impl<N: ProviderNodeTypes> HeaderProvider for ProviderFactory<N> {
self.static_file_provider.header_by_number(num)
}

fn header_td(&self, hash: BlockHash) -> ProviderResult<Option<U256>> {
self.provider()?.header_td(hash)
}

fn header_td_by_number(&self, number: BlockNumber) -> ProviderResult<Option<U256>> {
self.static_file_provider.header_td_by_number(number)
}

fn headers_range(
&self,
range: impl RangeBounds<BlockNumber>,
Expand Down
26 changes: 3 additions & 23 deletions crates/storage/provider/src/providers/database/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ use alloy_eips::BlockHashOrNumber;
use alloy_primitives::{
keccak256,
map::{hash_map, B256Map, HashMap, HashSet},
Address, BlockHash, BlockNumber, TxHash, TxNumber, B256, U256,
Address, BlockHash, BlockNumber, TxHash, TxNumber, B256,
};
use itertools::Itertools;
use rayon::slice::ParallelSliceMut;
use reth_chain_state::ExecutedBlock;
use reth_chainspec::{ChainInfo, ChainSpecProvider, EthChainSpec, EthereumHardforks};
use reth_chainspec::{ChainInfo, ChainSpecProvider, EthChainSpec};
use reth_db_api::{
cursor::{DbCursorRO, DbCursorRW, DbDupCursorRO, DbDupCursorRW},
database::Database,
Expand Down Expand Up @@ -971,26 +971,6 @@ impl<TX: DbTx + 'static, N: NodeTypesForProvider> HeaderProvider for DatabasePro
self.static_file_provider.header_by_number(num)
}

fn header_td(&self, block_hash: BlockHash) -> ProviderResult<Option<U256>> {
if let Some(num) = self.block_number(block_hash)? {
self.header_td_by_number(num)
} else {
Ok(None)
}
}

fn header_td_by_number(&self, number: BlockNumber) -> ProviderResult<Option<U256>> {
if self.chain_spec.is_paris_active_at_block(number) &&
let Some(td) = self.chain_spec.final_paris_total_difficulty()
{
// if this block is higher than the final paris(merge) block, return the final paris
// difficulty
return Ok(Some(td))
}

self.static_file_provider.header_td_by_number(number)
}

fn headers_range(
&self,
range: impl RangeBounds<BlockNumber>,
Expand Down Expand Up @@ -2838,7 +2818,7 @@ impl<TX: DbTxMut + DbTx + 'static, N: NodeTypesForProvider + 'static> BlockWrite
block.header().difficulty()
} else {
let parent_block_number = block_number - 1;
let parent_ttd = self.header_td_by_number(parent_block_number)?.unwrap_or_default();
let parent_ttd = self.static_file_provider.header_td_by_number(parent_block_number)?.unwrap_or_default();
durations_recorder.record_relative(metrics::Action::GetParentTD);
parent_ttd + block.header().difficulty()
};
Expand Down
Loading
Loading