@@ -190,9 +190,13 @@ impl<
190190 // Create sync manager
191191 let received_filter_heights = stats. read ( ) . await . received_filter_heights . clone ( ) ;
192192 tracing:: info!( "Creating sequential sync manager" ) ;
193- let sync_manager =
194- SequentialSyncManager :: new ( & config, received_filter_heights, wallet. clone ( ) )
195- . map_err ( SpvError :: Sync ) ?;
193+ let sync_manager = SequentialSyncManager :: new (
194+ & config,
195+ received_filter_heights,
196+ wallet. clone ( ) ,
197+ state. clone ( ) ,
198+ )
199+ . map_err ( SpvError :: Sync ) ?;
196200
197201 // Create validation manager
198202 let validation = ValidationManager :: new ( config. validation_mode ) ;
@@ -343,20 +347,6 @@ impl<
343347 match loaded_count {
344348 Ok ( loaded_count) => {
345349 tracing:: info!( "✅ Sync manager loaded {} headers from storage" , loaded_count) ;
346-
347- // IMPORTANT: Also load headers into the client's ChainState for normal sync
348- // This is needed because the status display reads from the client's ChainState
349- let state = self . state . read ( ) . await ;
350- let is_normal_sync = !state. synced_from_checkpoint ;
351- drop ( state) ; // Release the lock before loading headers
352-
353- if is_normal_sync && loaded_count > 0 {
354- tracing:: info!( "Loading headers into client ChainState for normal sync..." ) ;
355- if let Err ( e) = self . load_headers_into_client_state ( tip_height) . await {
356- tracing:: error!( "Failed to load headers into client ChainState: {}" , e) ;
357- // This is not critical for normal sync, continue anyway
358- }
359- }
360350 }
361351 Err ( e) => {
362352 tracing:: error!( "Failed to load headers into sync manager: {}" , e) ;
@@ -1940,79 +1930,6 @@ impl<
19401930 Ok ( true )
19411931 }
19421932
1943- /// Load headers from storage into the client's ChainState.
1944- /// This is used during normal sync to ensure the status display shows correct header count.
1945- async fn load_headers_into_client_state ( & mut self , tip_height : u32 ) -> Result < ( ) > {
1946- if tip_height == 0 {
1947- return Ok ( ( ) ) ;
1948- }
1949-
1950- tracing:: debug!( "Loading {} headers from storage into client ChainState" , tip_height) ;
1951- let start_time = Instant :: now ( ) ;
1952-
1953- // Load headers in batches to avoid memory spikes
1954- const BATCH_SIZE : u32 = 10_000 ;
1955- let mut loaded_count = 0u32 ;
1956-
1957- // Start from height 1 (genesis is already in ChainState)
1958- let mut current_height = 1u32 ;
1959-
1960- while current_height <= tip_height {
1961- let end_height = ( current_height + BATCH_SIZE - 1 ) . min ( tip_height) ;
1962-
1963- // Load batch of headers from storage
1964- let headers = {
1965- let storage = self . storage . lock ( ) . await ;
1966- storage
1967- . load_headers ( current_height..end_height + 1 )
1968- . await
1969- . map_err ( SpvError :: Storage ) ?
1970- } ;
1971-
1972- if headers. is_empty ( ) {
1973- tracing:: warn!(
1974- "No headers found for range {}..{} - storage may be incomplete" ,
1975- current_height,
1976- end_height + 1
1977- ) ;
1978- break ;
1979- }
1980-
1981- // Add headers to client's chain state
1982- {
1983- let mut state = self . state . write ( ) . await ;
1984- for header in headers {
1985- state. add_header ( header) ;
1986- loaded_count += 1 ;
1987- }
1988- }
1989-
1990- // Progress logging for large header counts
1991- if loaded_count % 50_000 == 0 || loaded_count == tip_height {
1992- let elapsed = start_time. elapsed ( ) ;
1993- let headers_per_sec = loaded_count as f64 / elapsed. as_secs_f64 ( ) ;
1994- tracing:: debug!(
1995- "Loaded {}/{} headers into client ChainState ({:.0} headers/sec)" ,
1996- loaded_count,
1997- tip_height,
1998- headers_per_sec
1999- ) ;
2000- }
2001-
2002- current_height = end_height + 1 ;
2003- }
2004-
2005- let elapsed = start_time. elapsed ( ) ;
2006- tracing:: info!(
2007- "✅ Loaded {} headers into client ChainState in {:.2}s ({:.0} headers/sec)" ,
2008- loaded_count,
2009- elapsed. as_secs_f64( ) ,
2010- loaded_count as f64 / elapsed. as_secs_f64( )
2011- ) ;
2012-
2013- Ok ( ( ) )
2014- }
2015-
20161933 /// Rollback chain state to a specific height.
20171934 async fn rollback_to_height ( & mut self , target_height : u32 ) -> Result < ( ) > {
20181935 tracing:: info!( "Rolling back chain state to height {}" , target_height) ;
@@ -2255,9 +2172,9 @@ impl<
22552172 self . config . network ,
22562173 ) ;
22572174
2258- // Clone the chain state for storage and sync manager
2175+ // Clone the chain state for storage
22592176 let chain_state_for_storage = ( * chain_state) . clone ( ) ;
2260- let checkpoint_chain_state = ( * chain_state ) . clone ( ) ;
2177+ let headers_len = chain_state_for_storage . headers . len ( ) as u32 ;
22612178 drop ( chain_state) ;
22622179
22632180 // Update storage with chain state including sync_base_height
@@ -2278,8 +2195,12 @@ impl<
22782195 checkpoint. height
22792196 ) ;
22802197
2281- // Update the sync manager's chain state with the checkpoint-initialized state
2282- self . sync_manager . set_chain_state ( checkpoint_chain_state) ;
2198+ // Update the sync manager's cached flags from the checkpoint-initialized state
2199+ self . sync_manager . update_chain_state_cache (
2200+ true ,
2201+ checkpoint. height ,
2202+ headers_len,
2203+ ) ;
22832204 tracing:: info!(
22842205 "Updated sync manager with checkpoint-initialized chain state"
22852206 ) ;
0 commit comments