@@ -69,25 +69,46 @@ impl<
6969 let tip_height =
7070 self . storage . get_filter_tip_height ( ) . await . map_err ( SpvError :: Storage ) ?. unwrap_or ( 0 ) ;
7171
72- // TODO: Get earliest height from wallet's birth height or earliest address usage
73- // For now, default to last 100 blocks
74- let earliest_height = tip_height. saturating_sub ( 99 ) ;
75-
76- let num_blocks = num_blocks. unwrap_or ( 100 ) ;
72+ // Determine how many blocks to request
73+ let num_blocks = num_blocks. unwrap_or ( 100 ) . max ( 1 ) ;
7774 let default_start = tip_height. saturating_sub ( num_blocks - 1 ) ;
78- let start_height = earliest_height. min ( default_start) ; // Go back to the earliest required height
79- let actual_count = tip_height - start_height + 1 ; // Actual number of blocks available
75+
76+ // Ask the wallet for an earliest rescan height, falling back to the default window.
77+ let wallet_hint = self . sync_manager . wallet_birth_height_hint ( ) . await ;
78+ let mut start_height = wallet_hint. unwrap_or ( default_start) . min ( default_start) ;
79+
80+ // Respect any user-provided start height hint from the configuration.
81+ if let Some ( config_start) = self . sync_manager . config_start_height ( ) {
82+ let capped = config_start. min ( tip_height) ;
83+ start_height = start_height. max ( capped) ;
84+ }
85+
86+ // Make sure we never request past the current tip
87+ start_height = start_height. min ( tip_height) ;
88+
89+ let actual_count = if start_height <= tip_height {
90+ tip_height - start_height + 1
91+ } else {
92+ 0
93+ } ;
8094
8195 tracing:: info!(
8296 "Requesting filters from height {} to {} ({} blocks based on filter tip height)" ,
8397 start_height,
8498 tip_height,
8599 actual_count
86100 ) ;
101+ if let Some ( hint) = wallet_hint {
102+ tracing:: debug!( "Wallet hint for earliest required height: {}" , hint) ;
103+ }
87104 tracing:: info!( "Filter processing and matching will happen automatically in background thread as CFilter messages arrive" ) ;
88105
89106 // Send filter requests - processing will happen automatically in the background
90- self . sync_filters_coordinated ( start_height, actual_count) . await ?;
107+ if actual_count > 0 {
108+ self . sync_filters_coordinated ( start_height, actual_count) . await ?;
109+ } else {
110+ tracing:: debug!( "No filters requested because calculated range is empty" ) ;
111+ }
91112
92113 // Return empty vector since matching happens asynchronously in the filter processor thread
93114 // Actual matches will be processed and blocks requested automatically when CFilter messages arrive
0 commit comments