diff --git a/bin/reth/src/commands/import.rs b/bin/reth/src/commands/import.rs index 578b1ff8eb..9f6161a2cf 100644 --- a/bin/reth/src/commands/import.rs +++ b/bin/reth/src/commands/import.rs @@ -18,7 +18,13 @@ use reth_downloaders::{ bodies::bodies::BodiesDownloaderBuilder, file_client::FileClient, headers::reverse_headers::ReverseHeadersDownloaderBuilder, }; -use reth_interfaces::consensus::Consensus; +use reth_interfaces::{ + consensus::Consensus, + p2p::{ + bodies::downloader::BodyDownloader, + headers::downloader::{HeaderDownloader, SyncTarget}, + }, +}; use reth_node_core::{events::node::NodeEvent, init::init_genesis}; use reth_node_ethereum::EthEvmConfig; use reth_primitives::{stage::StageId, ChainSpec, PruneModes, B256, OP_RETH_MAINNET_BELOW_BEDROCK}; @@ -183,13 +189,18 @@ impl ImportCommand { eyre::bail!("unable to import non canonical blocks"); } - let header_downloader = ReverseHeadersDownloaderBuilder::new(config.stages.headers) + let mut header_downloader = ReverseHeadersDownloaderBuilder::new(config.stages.headers) .build(file_client.clone(), consensus.clone()) .into_task(); + header_downloader.update_local_head(file_client.tip_header().unwrap()); + header_downloader.update_sync_target(SyncTarget::Tip(file_client.start().unwrap())); - let body_downloader = BodiesDownloaderBuilder::new(config.stages.bodies) + let mut body_downloader = BodiesDownloaderBuilder::new(config.stages.bodies) .build(file_client.clone(), consensus.clone(), provider_factory.clone()) .into_task(); + body_downloader + .set_download_range(file_client.min_block().unwrap()..=file_client.max_block().unwrap()) + .expect("failed to set download range"); let (tip_tx, tip_rx) = watch::channel(B256::ZERO); let factory = diff --git a/crates/net/downloaders/src/file_client.rs b/crates/net/downloaders/src/file_client.rs index 1f09ad787b..9ebde1b705 100644 --- a/crates/net/downloaders/src/file_client.rs +++ b/crates/net/downloaders/src/file_client.rs @@ -8,7 +8,8 @@ use reth_interfaces::p2p::{ priority::Priority, }; use reth_primitives::{ - BlockBody, BlockHash, BlockHashOrNumber, BlockNumber, Header, HeadersDirection, PeerId, B256, + BlockBody, BlockHash, BlockHashOrNumber, BlockNumber, Header, HeadersDirection, PeerId, + SealedHeader, B256, }; use std::{collections::HashMap, path::Path}; use thiserror::Error; @@ -119,11 +120,33 @@ impl FileClient { self.headers.get(&((self.headers.len() - 1) as u64)).map(|h| h.hash_slow()) } + /// Get the start hash of the chain. + pub fn start(&self) -> Option { + self.headers.get(&self.min_block()?).map(|h| h.hash_slow()) + } + /// Returns the highest block number of this client has or `None` if empty pub fn max_block(&self) -> Option { self.headers.keys().max().copied() } + /// Returns the lowest block number of this client has or `None` if empty + pub fn min_block(&self) -> Option { + self.headers.keys().min().copied() + } + + /// Clones and returns the highest header of this client has or `None` if empty. Seals header + /// before returning. + pub fn tip_header(&self) -> Option { + self.headers.get(&self.max_block()?).map(|h| h.clone().seal_slow()) + } + + /// Clones and returns the lowest header of this client has or `None` if empty. Seals header + /// before returning. + pub fn start_header(&self) -> Option { + self.headers.get(&self.min_block()?).map(|h| h.clone().seal_slow()) + } + /// Returns true if all blocks are canonical (no gaps) pub fn has_canonical_blocks(&self) -> bool { if self.headers.is_empty() {