diff --git a/crates/cli/commands/src/stage/run.rs b/crates/cli/commands/src/stage/run.rs index 254b5fe64..71f3c4b74 100644 --- a/crates/cli/commands/src/stage/run.rs +++ b/crates/cli/commands/src/stage/run.rs @@ -45,8 +45,7 @@ use reth_stages::{ IndexStorageHistoryStage, MerkleStage, SenderRecoveryStage, StorageHashingStage, TransactionLookupStage, }, - ExecInput, ExecOutput, ExecutionStageThresholds, Stage, StageError, StageExt, UnwindInput, - UnwindOutput, + ExecInput, ExecOutput, ExecutionStageThresholds, Stage, StageExt, UnwindInput, UnwindOutput, }; use std::{any::Any, net::SocketAddr, sync::Arc, time::Instant}; use tokio::sync::watch; @@ -190,16 +189,18 @@ impl // Use `to` as the tip for the stage let tip: P::BlockHeader = loop { - match fetch_client.get_header(BlockHashOrNumber::Number(self.to)).await { - Ok(header) => break header, - Err(error) if error.is_retryable() => { - warn!(target: "reth::cli", "Error requesting header: {error}. Retrying...") + match fetch_client.get_header(BlockHashOrNumber::Number(self.to)).await { + Ok(header) => { + if let Some(header) = header.into_data() { + break header } - Err(error) => return Err(error.into()), } + Err(error) if error.is_retryable() => { + warn!(target: "reth::cli", "Error requesting header: {error}. Retrying...") + } + Err(error) => return Err(error.into()), } - .into_data() - .ok_or(StageError::MissingSyncGap)?; + }; let (_, rx) = watch::channel(tip.hash_slow()); ( Box::new(HeaderStage::new( diff --git a/crates/net/p2p/src/headers/client.rs b/crates/net/p2p/src/headers/client.rs index 606d8f389..23cfcdf9d 100644 --- a/crates/net/p2p/src/headers/client.rs +++ b/crates/net/p2p/src/headers/client.rs @@ -94,6 +94,8 @@ pub trait HeadersClient: DownloadClient { } /// A Future that resolves to a single block body. +/// +/// Returns `None` if the peer responded with an empty header response. #[derive(Debug)] #[must_use = "futures do nothing unless polled"] pub struct SingleHeaderRequest {