Skip to content

Commit c01c737

Browse files
authored
fix: ensure that downloader sync gap is only set once (paradigmxyz#16693)
1 parent c1b42d4 commit c01c737

File tree

3 files changed

+13
-7
lines changed

3 files changed

+13
-7
lines changed

crates/ethereum/node/tests/e2e/p2p.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ async fn test_reorg_through_backfill() -> eyre::Result<()> {
187187

188188
// Produce an unfinalized fork chain with 5 blocks
189189
second_node.payload.timestamp = head.header.timestamp;
190-
advance_with_random_transactions(&mut second_node, 5, &mut rng, false).await?;
190+
advance_with_random_transactions(&mut second_node, 10, &mut rng, false).await?;
191191

192192
// Now reorg second node to the finalized canonical head
193193
let head = first_provider.get_block_by_number(100.into()).await?.unwrap();

crates/net/p2p/src/headers/downloader.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ impl SyncTarget {
8080
}
8181

8282
/// Represents a gap to sync: from `local_head` to `target`
83-
#[derive(Clone, Debug)]
84-
pub struct HeaderSyncGap<H = Header> {
83+
#[derive(Clone, Debug, PartialEq, Eq)]
84+
pub struct HeaderSyncGap<H: Sealable = Header> {
8585
/// The local head block. Represents lower bound of sync range.
8686
pub local_head: SealedHeader<H>,
8787

crates/stages/stages/src/stages/headers.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,6 @@ where
214214
let target = SyncTarget::Tip(*self.tip.borrow());
215215
let gap = HeaderSyncGap { local_head, target };
216216
let tip = gap.target.tip();
217-
self.sync_gap = Some(gap.clone());
218217

219218
// Nothing to sync
220219
if gap.is_closed() {
@@ -232,7 +231,10 @@ where
232231
let local_head_number = gap.local_head.number();
233232

234233
// let the downloader know what to sync
235-
self.downloader.update_sync_gap(gap.local_head, gap.target);
234+
if self.sync_gap != Some(gap.clone()) {
235+
self.sync_gap = Some(gap.clone());
236+
self.downloader.update_sync_gap(gap.local_head, gap.target);
237+
}
236238

237239
// We only want to stop once we have all the headers on ETL filespace (disk).
238240
loop {
@@ -263,13 +265,17 @@ where
263265
}
264266
Some(Err(HeadersDownloaderError::DetachedHead { local_head, header, error })) => {
265267
error!(target: "sync::stages::headers", %error, "Cannot attach header to head");
268+
self.sync_gap = None;
266269
return Poll::Ready(Err(StageError::DetachedHead {
267270
local_head: Box::new(local_head.block_with_parent()),
268271
header: Box::new(header.block_with_parent()),
269272
error,
270273
}))
271274
}
272-
None => return Poll::Ready(Err(StageError::ChannelClosed)),
275+
None => {
276+
self.sync_gap = None;
277+
return Poll::Ready(Err(StageError::ChannelClosed))
278+
}
273279
}
274280
}
275281
}
@@ -279,7 +285,7 @@ where
279285
fn execute(&mut self, provider: &Provider, input: ExecInput) -> Result<ExecOutput, StageError> {
280286
let current_checkpoint = input.checkpoint();
281287

282-
if self.sync_gap.as_ref().ok_or(StageError::MissingSyncGap)?.is_closed() {
288+
if self.sync_gap.take().ok_or(StageError::MissingSyncGap)?.is_closed() {
283289
self.is_etl_ready = false;
284290
return Ok(ExecOutput::done(current_checkpoint))
285291
}

0 commit comments

Comments
 (0)