@@ -86,24 +86,22 @@ impl ExecInput {
8686 /// Return the next block range determined the number of transactions within it.
8787 /// This function walks the block indices until either the end of the range is reached or
8888 /// the number of transactions exceeds the threshold.
89+ ///
90+ /// Returns [`None`] if no transactions are found for the current execution input.
8991 #[ instrument( level = "debug" , target = "sync::stages" , skip( provider) , ret) ]
9092 pub fn next_block_range_with_transaction_threshold < Provider > (
9193 & self ,
9294 provider : & Provider ,
9395 tx_threshold : u64 ,
94- ) -> Result < TransactionRangeOutput , StageError >
96+ ) -> Result < Option < TransactionRangeOutput > , StageError >
9597 where
9698 Provider : StaticFileProviderFactory + BlockReader ,
9799 {
98100 // Get lowest available block number for transactions
99101 let Some ( lowest_transactions_block) =
100102 provider. static_file_provider ( ) . get_lowest_range_start ( StaticFileSegment :: Transactions )
101103 else {
102- return Ok ( TransactionRangeOutput {
103- tx_range : 0 ..0 ,
104- block_range : 0 ..=0 ,
105- is_final_range : true ,
106- } ) ;
104+ return Ok ( None )
107105 } ;
108106
109107 // We can only process transactions that have associated static files, so we cap the start
@@ -115,6 +113,13 @@ impl ExecInput {
115113 let start_block = self . next_block ( ) . max ( lowest_transactions_block) ;
116114 let target_block = self . target ( ) ;
117115
116+ // If the start block is greater than the target, then there's no transactions to process
117+ // and we return early. It's possible to trigger this scenario when running `reth
118+ // stage run` manually for a range of transactions that doesn't exist.
119+ if start_block > target_block {
120+ return Ok ( None )
121+ }
122+
118123 let start_block_body = provider
119124 . block_body_indices ( start_block) ?
120125 . ok_or ( ProviderError :: BlockBodyIndicesNotFound ( start_block) ) ?;
@@ -129,11 +134,7 @@ impl ExecInput {
129134
130135 if all_tx_cnt == 0 {
131136 // if there is no more transaction return back.
132- return Ok ( TransactionRangeOutput {
133- tx_range : first_tx_num..first_tx_num,
134- block_range : start_block..=target_block,
135- is_final_range : true ,
136- } )
137+ return Ok ( None )
137138 }
138139
139140 // get block of this tx
@@ -154,11 +155,11 @@ impl ExecInput {
154155 } ;
155156
156157 let tx_range = first_tx_num..next_tx_num;
157- Ok ( TransactionRangeOutput {
158+ Ok ( Some ( TransactionRangeOutput {
158159 tx_range,
159160 block_range : start_block..=end_block,
160161 is_final_range,
161- } )
162+ } ) )
162163 }
163164}
164165
@@ -355,9 +356,7 @@ mod tests {
355356 let range_output = exec_input
356357 . next_block_range_with_transaction_threshold ( & provider_factory, 10 )
357358 . unwrap ( ) ;
358- assert_eq ! ( range_output. tx_range, 0 ..0 ) ;
359- assert_eq ! ( range_output. block_range, 0 ..=0 ) ;
360- assert ! ( range_output. is_final_range) ;
359+ assert ! ( range_output. is_none( ) ) ;
361360 }
362361
363362 // With checkpoint at block 10, without transactions in static files
@@ -368,9 +367,7 @@ mod tests {
368367 let range_output = exec_input
369368 . next_block_range_with_transaction_threshold ( & provider_factory, 10 )
370369 . unwrap ( ) ;
371- assert_eq ! ( range_output. tx_range, 0 ..0 ) ;
372- assert_eq ! ( range_output. block_range, 0 ..=0 ) ;
373- assert ! ( range_output. is_final_range) ;
370+ assert ! ( range_output. is_none( ) ) ;
374371 }
375372
376373 // Without checkpoint, with transactions in static files starting from block 1
@@ -396,6 +393,7 @@ mod tests {
396393
397394 let range_output = exec_input
398395 . next_block_range_with_transaction_threshold ( & provider_factory, 10 )
396+ . unwrap ( )
399397 . unwrap ( ) ;
400398 assert_eq ! ( range_output. tx_range, 0 ..2 ) ;
401399 assert_eq ! ( range_output. block_range, 1 ..=1 ) ;
@@ -424,6 +422,7 @@ mod tests {
424422
425423 let range_output = exec_input
426424 . next_block_range_with_transaction_threshold ( & provider_factory, 10 )
425+ . unwrap ( )
427426 . unwrap ( ) ;
428427 assert_eq ! ( range_output. tx_range, 2 ..3 ) ;
429428 assert_eq ! ( range_output. block_range, 2 ..=2 ) ;
@@ -445,6 +444,7 @@ mod tests {
445444
446445 let range_output = exec_input
447446 . next_block_range_with_transaction_threshold ( & provider_factory, 10 )
447+ . unwrap ( )
448448 . unwrap ( ) ;
449449 assert_eq ! ( range_output. tx_range, 2 ..3 ) ;
450450 assert_eq ! ( range_output. block_range, 2 ..=2 ) ;
@@ -473,6 +473,7 @@ mod tests {
473473
474474 let range_output = exec_input
475475 . next_block_range_with_transaction_threshold ( & provider_factory, 10 )
476+ . unwrap ( )
476477 . unwrap ( ) ;
477478 assert_eq ! ( range_output. tx_range, 3 ..4 ) ;
478479 assert_eq ! ( range_output. block_range, 3 ..=3 ) ;
0 commit comments