diff --git a/crates/storage/provider/src/providers/database/provider.rs b/crates/storage/provider/src/providers/database/provider.rs index 1f0a0aa391a..613364a903f 100644 --- a/crates/storage/provider/src/providers/database/provider.rs +++ b/crates/storage/provider/src/providers/database/provider.rs @@ -2918,21 +2918,24 @@ impl BlockWrite self.tx.delete::(hash, None)?; } - // Get highest static file block for the total block range - let highest_static_file_block = self - .static_file_provider() - .get_highest_static_file_block(StaticFileSegment::Headers) - .expect("todo: error handling, headers should exist"); - - // IMPORTANT: we use `highest_static_file_block.saturating_sub(block_number)` to make sure - // we remove only what is ABOVE the block. + // Get highest static file block for the total block range. // - // i.e., if the highest static file block is 8, we want to remove above block 5 only, we - // will have three blocks to remove, which will be block 8, 7, and 6. - debug!(target: "providers::db", ?block, "Removing static file blocks above block_number"); - self.static_file_provider() - .get_writer(block, StaticFileSegment::Headers)? - .prune_headers(highest_static_file_block.saturating_sub(block))?; + // If there are no header static files yet, there is nothing to prune. + if let Some(highest_static_file_block) = + self.static_file_provider().get_highest_static_file_block(StaticFileSegment::Headers) + { + // IMPORTANT: we use `highest_static_file_block.saturating_sub(block_number)` to make sure + // we remove only what is ABOVE the block. + // + // i.e., if the highest static file block is 8, we want to remove above block 5 only, we + // will have three blocks to remove, which will be block 8, 7, and 6. + debug!(target: "providers::db", ?block, "Removing static file blocks above block_number"); + self.static_file_provider() + .get_writer(block, StaticFileSegment::Headers)? + .prune_headers(highest_static_file_block.saturating_sub(block))?; + } else { + debug!(target: "providers::db", ?block, "No header static files found; skipping static file pruning"); + } // First transaction to be removed let unwind_tx_from = self @@ -3164,6 +3167,15 @@ mod tests { }; use reth_testing_utils::generators::{self, random_block, BlockParams}; + #[test] + fn test_remove_blocks_above_without_static_file_headers() { + let factory = create_test_provider_factory(); + let provider_rw = factory.provider_rw().unwrap(); + + // There are no static files yet in a fresh test provider. This should not panic. + assert!(provider_rw.remove_blocks_above(0).is_ok()); + } + #[test] fn test_receipts_by_block_range_empty_range() { let factory = create_test_provider_factory();