From b96a30821f5d345a5db0c34692500544d0fc3ff4 Mon Sep 17 00:00:00 2001 From: Georgios Konstantopoulos Date: Sat, 17 Jan 2026 00:33:27 +0000 Subject: [PATCH] fix(engine): request head block download when not buffered after backfill (#21150) --- crates/engine/tree/src/tree/mod.rs | 12 ++++++++++++ crates/engine/tree/src/tree/tests.rs | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/crates/engine/tree/src/tree/mod.rs b/crates/engine/tree/src/tree/mod.rs index 6796e098d1..275a2c47f6 100644 --- a/crates/engine/tree/src/tree/mod.rs +++ b/crates/engine/tree/src/tree/mod.rs @@ -1676,6 +1676,18 @@ where ))); return Ok(()); } + } else { + // We don't have the head block or any of its ancestors buffered. Request + // a download for the head block which will then trigger further sync. + debug!( + target: "engine::tree", + head_hash = %sync_target_state.head_block_hash, + "Backfill complete but head block not buffered, requesting download" + ); + self.emit_event(EngineApiEvent::Download(DownloadRequest::single_block( + sync_target_state.head_block_hash, + ))); + return Ok(()); } // try to close the gap by executing buffered blocks that are child blocks of the new head diff --git a/crates/engine/tree/src/tree/tests.rs b/crates/engine/tree/src/tree/tests.rs index adfc62ef4b..dd576ed37f 100644 --- a/crates/engine/tree/src/tree/tests.rs +++ b/crates/engine/tree/src/tree/tests.rs @@ -1008,6 +1008,15 @@ async fn test_engine_tree_live_sync_transition_required_blocks_requested() { _ => panic!("Unexpected event: {event:#?}"), } + // After backfill completes with head not buffered, we also request head download + let event = test_harness.from_tree_rx.recv().await.unwrap(); + match event { + EngineApiEvent::Download(DownloadRequest::BlockSet(hash_set)) => { + assert_eq!(hash_set, HashSet::from_iter([main_chain_last_hash])); + } + _ => panic!("Unexpected event: {event:#?}"), + } + let _ = test_harness .tree .on_engine_message(FromEngine::DownloadedBlocks(vec![main_chain