From b38f7ada151596757ae05e016b1f32a1fe5c18b5 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Thu, 19 Sep 2024 14:32:57 +0100 Subject: [PATCH 01/14] rename const to DEFAULT_BLOCKS_PER_STATIC_FILE --- crates/static-file/types/src/lib.rs | 6 +++--- .../provider/src/providers/static_file/manager.rs | 10 ++++++---- .../storage/provider/src/providers/static_file/mod.rs | 2 -- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/static-file/types/src/lib.rs b/crates/static-file/types/src/lib.rs index 190ff3432b67..48fd0a4a4e7f 100644 --- a/crates/static-file/types/src/lib.rs +++ b/crates/static-file/types/src/lib.rs @@ -16,7 +16,7 @@ pub use compression::Compression; pub use segment::{SegmentConfig, SegmentHeader, SegmentRangeInclusive, StaticFileSegment}; /// Default static file block count. -pub const BLOCKS_PER_STATIC_FILE: u64 = 500_000; +pub const DEFAULT_BLOCKS_PER_STATIC_FILE: u64 = 500_000; /// Highest static file block numbers, per data segment. #[derive(Debug, Clone, Copy, Default, Eq, PartialEq)] @@ -65,6 +65,6 @@ impl HighestStaticFiles { /// Each static file has a fixed number of blocks. This gives out the range where the requested /// block is positioned. Used for segment filename. pub const fn find_fixed_range(block: BlockNumber) -> SegmentRangeInclusive { - let start = (block / BLOCKS_PER_STATIC_FILE) * BLOCKS_PER_STATIC_FILE; - SegmentRangeInclusive::new(start, start + BLOCKS_PER_STATIC_FILE - 1) + let start = (block / DEFAULT_BLOCKS_PER_STATIC_FILE) * DEFAULT_BLOCKS_PER_STATIC_FILE; + SegmentRangeInclusive::new(start, start + DEFAULT_BLOCKS_PER_STATIC_FILE - 1) } diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 074d109c35be..2f2c0fa56c92 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -1,7 +1,6 @@ use super::{ metrics::StaticFileProviderMetrics, writer::StaticFileWriters, LoadedJar, StaticFileJarProvider, StaticFileProviderRW, StaticFileProviderRWRefMut, - BLOCKS_PER_STATIC_FILE, }; use crate::{ to_range, BlockHashReader, BlockNumReader, BlockReader, BlockSource, DatabaseProvider, @@ -27,7 +26,10 @@ use reth_db_api::{ }; use reth_nippy_jar::{NippyJar, NippyJarChecker, CONFIG_FILE_EXTENSION}; use reth_primitives::{ - static_file::{find_fixed_range, HighestStaticFiles, SegmentHeader, SegmentRangeInclusive}, + static_file::{ + find_fixed_range, HighestStaticFiles, SegmentHeader, SegmentRangeInclusive, + DEFAULT_BLOCKS_PER_STATIC_FILE, + }, Block, BlockWithSenders, Header, Receipt, SealedBlock, SealedBlockWithSenders, SealedHeader, StaticFileSegment, TransactionMeta, TransactionSigned, TransactionSignedNoHash, Withdrawal, Withdrawals, @@ -893,8 +895,8 @@ impl StaticFileProvider { return Ok(Some(res)) } range = SegmentRangeInclusive::new( - range.start().saturating_sub(BLOCKS_PER_STATIC_FILE), - range.end().saturating_sub(BLOCKS_PER_STATIC_FILE), + range.start().saturating_sub(DEFAULT_BLOCKS_PER_STATIC_FILE), + range.end().saturating_sub(DEFAULT_BLOCKS_PER_STATIC_FILE), ); } } diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index a4bd2cf574bc..016b4ed04c31 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -14,8 +14,6 @@ use reth_primitives::{static_file::SegmentHeader, StaticFileSegment}; use reth_storage_errors::provider::{ProviderError, ProviderResult}; use std::{ops::Deref, sync::Arc}; -const BLOCKS_PER_STATIC_FILE: u64 = 500_000; - /// Alias type for each specific `NippyJar`. type LoadedJarRef<'a> = dashmap::mapref::one::Ref<'a, (u64, StaticFileSegment), LoadedJar>; From 1bc43408c8803faad713fd6af49baf1f41c455eb Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Thu, 19 Sep 2024 15:17:23 +0100 Subject: [PATCH 02/14] add blocks_per_file to StaticFileProvider fields --- crates/cli/commands/src/db/clear.rs | 5 +-- crates/cli/commands/src/db/stats.rs | 4 +- crates/cli/commands/src/stage/drop.rs | 5 +-- crates/static-file/types/src/lib.rs | 9 +++-- .../src/providers/static_file/manager.rs | 38 +++++++++++++------ .../provider/src/providers/static_file/mod.rs | 9 +++-- .../src/providers/static_file/writer.rs | 12 ++++-- 7 files changed, 51 insertions(+), 31 deletions(-) diff --git a/crates/cli/commands/src/db/clear.rs b/crates/cli/commands/src/db/clear.rs index de92c7dcacc4..fe784536190e 100644 --- a/crates/cli/commands/src/db/clear.rs +++ b/crates/cli/commands/src/db/clear.rs @@ -7,7 +7,7 @@ use reth_db_api::{ }; use reth_node_builder::NodeTypesWithDB; use reth_provider::{ProviderFactory, StaticFileProviderFactory}; -use reth_static_file_types::{find_fixed_range, StaticFileSegment}; +use reth_static_file_types::StaticFileSegment; /// The arguments for the `reth db clear` command #[derive(Parser, Debug)] @@ -32,8 +32,7 @@ impl Command { if let Some(segment_static_files) = static_files.get(&segment) { for (block_range, _) in segment_static_files { - static_file_provider - .delete_jar(segment, find_fixed_range(block_range.start()))?; + static_file_provider.delete_jar(segment, block_range.start())?; } } } diff --git a/crates/cli/commands/src/db/stats.rs b/crates/cli/commands/src/db/stats.rs index 051b4469ab9c..31af95c81e0f 100644 --- a/crates/cli/commands/src/db/stats.rs +++ b/crates/cli/commands/src/db/stats.rs @@ -12,7 +12,7 @@ use reth_fs_util as fs; use reth_node_builder::{NodeTypesWithDB, NodeTypesWithDBAdapter, NodeTypesWithEngine}; use reth_node_core::dirs::{ChainPath, DataDirPath}; use reth_provider::providers::StaticFileProvider; -use reth_static_file_types::{find_fixed_range, SegmentRangeInclusive}; +use reth_static_file_types::SegmentRangeInclusive; use std::{sync::Arc, time::Duration}; #[derive(Parser, Debug)] @@ -191,7 +191,7 @@ impl Command { ) = (0, 0, 0, 0, 0, 0); for (block_range, tx_range) in &ranges { - let fixed_block_range = find_fixed_range(block_range.start()); + let fixed_block_range = static_file_provider.find_fixed_range(block_range.start()); let jar_provider = static_file_provider .get_segment_provider(segment, || Some(fixed_block_range), None)? .ok_or_else(|| { diff --git a/crates/cli/commands/src/stage/drop.rs b/crates/cli/commands/src/stage/drop.rs index 8fcbaf044009..6571cbaae864 100644 --- a/crates/cli/commands/src/stage/drop.rs +++ b/crates/cli/commands/src/stage/drop.rs @@ -14,7 +14,7 @@ use reth_node_builder::NodeTypesWithEngine; use reth_node_core::args::StageEnum; use reth_provider::{writer::UnifiedStorageWriter, StaticFileProviderFactory}; use reth_stages::StageId; -use reth_static_file_types::{find_fixed_range, StaticFileSegment}; +use reth_static_file_types::StaticFileSegment; /// `reth drop-stage` command #[derive(Debug, Parser)] @@ -54,8 +54,7 @@ impl> Command { .sorted_by_key(|(block_range, _)| block_range.start()) .rev() { - static_file_provider - .delete_jar(static_file_segment, find_fixed_range(block_range.start()))?; + static_file_provider.delete_jar(static_file_segment, block_range.start())?; } } } diff --git a/crates/static-file/types/src/lib.rs b/crates/static-file/types/src/lib.rs index 48fd0a4a4e7f..380931138869 100644 --- a/crates/static-file/types/src/lib.rs +++ b/crates/static-file/types/src/lib.rs @@ -64,7 +64,10 @@ impl HighestStaticFiles { /// Each static file has a fixed number of blocks. This gives out the range where the requested /// block is positioned. Used for segment filename. -pub const fn find_fixed_range(block: BlockNumber) -> SegmentRangeInclusive { - let start = (block / DEFAULT_BLOCKS_PER_STATIC_FILE) * DEFAULT_BLOCKS_PER_STATIC_FILE; - SegmentRangeInclusive::new(start, start + DEFAULT_BLOCKS_PER_STATIC_FILE - 1) +pub const fn find_fixed_range( + block: BlockNumber, + blocks_per_static_file: u64, +) -> SegmentRangeInclusive { + let start = (block / blocks_per_static_file) * blocks_per_static_file; + SegmentRangeInclusive::new(start, start + blocks_per_static_file - 1) } diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 2f2c0fa56c92..3d5b26727936 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -211,6 +211,8 @@ pub struct StaticFileProviderInner { metrics: Option>, /// Access rights of the provider. access: StaticFileAccess, + /// Number of blocks per file. + blocks_per_file: u64, /// Write lock for when access is [`StaticFileAccess::RW`]. _lock_file: Option, } @@ -232,6 +234,7 @@ impl StaticFileProviderInner { path: path.as_ref().to_path_buf(), metrics: None, access, + blocks_per_file: DEFAULT_BLOCKS_PER_STATIC_FILE, _lock_file, }; @@ -241,9 +244,23 @@ impl StaticFileProviderInner { pub const fn is_read_only(&self) -> bool { self.access.is_read_only() } + + /// Each static file has a fixed number of blocks. This gives out the range where the requested + /// block is positioned. + pub const fn find_fixed_range(&self, block: BlockNumber) -> SegmentRangeInclusive { + find_fixed_range(block, self.blocks_per_file) + } } impl StaticFileProvider { + /// Set a custom number of blocks per file. + pub fn with_custom_blocks_per_file(self, blocks_per_file: u64) -> Self { + let mut provider = + Arc::try_unwrap(self.0).expect("should be called when initializing only"); + provider.blocks_per_file = blocks_per_file; + Self(Arc::new(provider)) + } + /// Enables metrics on the [`StaticFileProvider`]. pub fn with_metrics(self) -> Self { let mut provider = @@ -263,7 +280,7 @@ impl StaticFileProvider { let mut size = 0; for (block_range, _) in &ranges { - let fixed_block_range = find_fixed_range(block_range.start()); + let fixed_block_range = self.find_fixed_range(block_range.start()); let jar_provider = self .get_segment_provider(segment, || Some(fixed_block_range), None)? .ok_or(ProviderError::MissingStaticFileBlock(segment, block_range.start()))?; @@ -370,14 +387,11 @@ impl StaticFileProvider { self.map.remove(&(fixed_block_range_end, segment)); } - /// Given a segment and block range it deletes the jar and all files associated with it. + /// Given a segment and block, it deletes the jar and all files from the respective block range. /// /// CAUTION: destructive. Deletes files on disk. - pub fn delete_jar( - &self, - segment: StaticFileSegment, - fixed_block_range: SegmentRangeInclusive, - ) -> ProviderResult<()> { + pub fn delete_jar(&self, segment: StaticFileSegment, block: BlockNumber) -> ProviderResult<()> { + let fixed_block_range = self.find_fixed_range(block); let key = (fixed_block_range.end(), segment); let jar = if let Some((_, jar)) = self.map.remove(&key) { jar.jar @@ -436,7 +450,7 @@ impl StaticFileProvider { .read() .get(&segment) .filter(|max| **max >= block) - .map(|_| find_fixed_range(block)) + .map(|_| self.find_fixed_range(block)) } /// Gets a static file segment's fixed block range from the provider inner @@ -460,7 +474,7 @@ impl StaticFileProvider { } let tx_start = static_files_rev_iter.peek().map(|(tx_end, _)| *tx_end + 1).unwrap_or(0); if tx_start <= tx { - return Some(find_fixed_range(block_range.end())) + return Some(self.find_fixed_range(block_range.end())) } } None @@ -484,7 +498,7 @@ impl StaticFileProvider { Some(segment_max_block) => { // Update the max block for the segment max_block.insert(segment, segment_max_block); - let fixed_range = find_fixed_range(segment_max_block); + let fixed_range = self.find_fixed_range(segment_max_block); let jar = NippyJar::::load( &self.path.join(segment.filename(&fixed_range)), @@ -742,7 +756,7 @@ impl StaticFileProvider { pub fn check_segment_consistency(&self, segment: StaticFileSegment) -> ProviderResult<()> { if let Some(latest_block) = self.get_highest_static_file_block(segment) { let file_path = - self.directory().join(segment.filename(&find_fixed_range(latest_block))); + self.directory().join(segment.filename(&self.find_fixed_range(latest_block))); let jar = NippyJar::::load(&file_path) .map_err(|e| ProviderError::NippyJar(e.to_string()))?; @@ -889,7 +903,7 @@ impl StaticFileProvider { func: impl Fn(StaticFileJarProvider<'_>) -> ProviderResult>, ) -> ProviderResult> { if let Some(highest_block) = self.get_highest_static_file_block(segment) { - let mut range = find_fixed_range(highest_block); + let mut range = self.find_fixed_range(highest_block); while range.end() > 0 { if let Some(res) = func(self.get_or_create_jar_provider(segment, &range)?)? { return Ok(Some(res)) diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index 016b4ed04c31..86128a8a5ea3 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -60,7 +60,7 @@ mod tests { use rand::seq::SliceRandom; use reth_db::{CanonicalHeaders, HeaderNumbers, HeaderTerminalDifficulties, Headers}; use reth_db_api::transaction::DbTxMut; - use reth_primitives::static_file::find_fixed_range; + use reth_primitives::static_file::{find_fixed_range, DEFAULT_BLOCKS_PER_STATIC_FILE}; use reth_testing_utils::generators::{self, random_header_range}; #[test] @@ -72,9 +72,10 @@ mod tests { // Data sources let factory = create_test_provider_factory(); let static_files_path = tempfile::tempdir().unwrap(); - let static_file = static_files_path - .path() - .join(StaticFileSegment::Headers.filename(&find_fixed_range(*range.end()))); + let static_file = static_files_path.path().join( + StaticFileSegment::Headers + .filename(&find_fixed_range(*range.end(), DEFAULT_BLOCKS_PER_STATIC_FILE)), + ); // Setup data let mut headers = random_header_range( diff --git a/crates/storage/provider/src/providers/static_file/writer.rs b/crates/storage/provider/src/providers/static_file/writer.rs index b5e2a07cccfe..9cd80fff8acc 100644 --- a/crates/storage/provider/src/providers/static_file/writer.rs +++ b/crates/storage/provider/src/providers/static_file/writer.rs @@ -8,7 +8,7 @@ use reth_codecs::Compact; use reth_db_api::models::CompactU256; use reth_nippy_jar::{NippyJar, NippyJarError, NippyJarWriter}; use reth_primitives::{ - static_file::{find_fixed_range, SegmentHeader, SegmentRangeInclusive}, + static_file::{SegmentHeader, SegmentRangeInclusive}, Header, Receipt, StaticFileSegment, TransactionSignedNoHash, }; use reth_storage_errors::provider::{ProviderError, ProviderResult}; @@ -139,7 +139,7 @@ impl StaticFileProviderRW { let static_file_provider = Self::upgrade_provider_to_strong_reference(&reader); - let block_range = find_fixed_range(block); + let block_range = static_file_provider.find_fixed_range(block); let (jar, path) = match static_file_provider.get_segment_provider_from_block( segment, block_range.start(), @@ -328,8 +328,12 @@ impl StaticFileProviderRW { self.writer = writer; self.data_path = data_path; - *self.writer.user_header_mut() = - SegmentHeader::new(find_fixed_range(last_block + 1), None, None, segment); + *self.writer.user_header_mut() = SegmentHeader::new( + self.reader().find_fixed_range(last_block + 1), + None, + None, + segment, + ); } } From 09d442d99ee4ba734e988846f11a94371ccdad14 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Thu, 19 Sep 2024 15:17:37 +0100 Subject: [PATCH 03/14] remove Default from staticfileproviders --- crates/storage/provider/src/providers/static_file/manager.rs | 4 ++-- crates/storage/provider/src/test_utils/noop.rs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 3d5b26727936..6c3b4e4dbeeb 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -73,7 +73,7 @@ impl StaticFileAccess { } /// [`StaticFileProvider`] manages all existing [`StaticFileJarProvider`]. -#[derive(Debug, Default, Clone)] +#[derive(Debug, Clone)] pub struct StaticFileProvider(pub(crate) Arc); impl StaticFileProvider { @@ -195,7 +195,7 @@ impl Deref for StaticFileProvider { } /// [`StaticFileProviderInner`] manages all existing [`StaticFileJarProvider`]. -#[derive(Debug, Default)] +#[derive(Debug)] pub struct StaticFileProviderInner { /// Maintains a map which allows for concurrent access to different `NippyJars`, over different /// segments and ranges. diff --git a/crates/storage/provider/src/test_utils/noop.rs b/crates/storage/provider/src/test_utils/noop.rs index ee662db52dc0..059accbd9005 100644 --- a/crates/storage/provider/src/test_utils/noop.rs +++ b/crates/storage/provider/src/test_utils/noop.rs @@ -1,6 +1,7 @@ use std::{ collections::{HashMap, HashSet}, ops::{RangeBounds, RangeInclusive}, + path::PathBuf, sync::Arc, }; @@ -554,7 +555,7 @@ impl PruneCheckpointReader for NoopProvider { impl StaticFileProviderFactory for NoopProvider { fn static_file_provider(&self) -> StaticFileProvider { - StaticFileProvider::default() + StaticFileProvider::read_only(PathBuf::default(), false).unwrap() } } From 2bfd1f09ac71c79d376654632f4ae868553f9ad5 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Thu, 19 Sep 2024 15:20:54 +0100 Subject: [PATCH 04/14] use self.blocks_per_file instead --- crates/storage/provider/src/providers/static_file/manager.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 6c3b4e4dbeeb..7925ad5d5d20 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -909,8 +909,8 @@ impl StaticFileProvider { return Ok(Some(res)) } range = SegmentRangeInclusive::new( - range.start().saturating_sub(DEFAULT_BLOCKS_PER_STATIC_FILE), - range.end().saturating_sub(DEFAULT_BLOCKS_PER_STATIC_FILE), + range.start().saturating_sub(self.blocks_per_file), + range.end().saturating_sub(self.blocks_per_file), ); } } From 1a333e076f795345aa54f8c77cc40078435f057e Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:49:30 +0100 Subject: [PATCH 05/14] add test cases for header truncation --- .../provider/src/providers/static_file/mod.rs | 129 +++++++++++++++++- 1 file changed, 127 insertions(+), 2 deletions(-) diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index 86128a8a5ea3..7f423e0fbabe 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -58,10 +58,17 @@ mod tests { use crate::{test_utils::create_test_provider_factory, HeaderProvider}; use alloy_primitives::{B256, U256}; use rand::seq::SliceRandom; - use reth_db::{CanonicalHeaders, HeaderNumbers, HeaderTerminalDifficulties, Headers}; + use reth_db::{ + test_utils::create_test_static_files_dir, CanonicalHeaders, HeaderNumbers, + HeaderTerminalDifficulties, Headers, + }; use reth_db_api::transaction::DbTxMut; - use reth_primitives::static_file::{find_fixed_range, DEFAULT_BLOCKS_PER_STATIC_FILE}; + use reth_primitives::{ + static_file::{find_fixed_range, DEFAULT_BLOCKS_PER_STATIC_FILE}, + BlockHash, Header, + }; use reth_testing_utils::generators::{self, random_header_range}; + use std::{fs, path::Path}; #[test] fn test_snap() { @@ -141,4 +148,122 @@ mod tests { } } } + + #[test] + fn test_header_truncation() { + let (static_dir, _) = create_test_static_files_dir(); + + let blocks_per_file = 10; // Number of headers per file + let files_per_range = 3; // Number of files per range (data/conf/offset files) + let file_set_count = 3; // Number of sets of files to create + let initial_file_count = files_per_range * file_set_count + 1; // Includes lockfile + let tip = blocks_per_file * file_set_count - 1; // Initial highest block (29 in this case) + + // [ Headers Creation and Commit ] + { + let sf_rw = StaticFileProvider::read_write(&static_dir) + .expect("Failed to create static file provider") + .with_custom_blocks_per_file(blocks_per_file); + + let mut header_writer = sf_rw.latest_writer(StaticFileSegment::Headers).unwrap(); + + // Append headers from 0 to the tip (29) and commit + let mut header = Header::default(); + for num in 0..=tip { + header.number = num; + header_writer + .append_header(&header, U256::default(), &BlockHash::default()) + .unwrap(); + } + header_writer.commit().unwrap(); + } + + // Helper function to prune headers and validate truncation results + fn prune_and_validate( + writer: &mut StaticFileProviderRWRefMut<'_>, + sf_rw: &StaticFileProvider, + static_dir: impl AsRef, + prune_count: u64, + expected_tip: Option, + expected_file_count: u64, + ) { + writer.prune_headers(prune_count).unwrap(); + writer.commit().unwrap(); + + // Validate the highest block after pruning + assert_eq!( + sf_rw.get_highest_static_file_block(StaticFileSegment::Headers), + expected_tip + ); + + // Validate the number of files remaining in the directory + assert_eq!(fs::read_dir(static_dir).unwrap().count(), expected_file_count as usize); + } + + // [ Test Cases ] + type PruneCount = u64; + type ExpectedTip = u64; + type ExpectedFileCount = u64; + let mut tmp_tip = tip; + let test_cases: Vec<(PruneCount, Option, ExpectedFileCount)> = vec![ + // Case 1: Pruning 1 header + { + tmp_tip -= 1; + (1, Some(tmp_tip), initial_file_count) + }, + // Case 2: Pruning remaining rows from file should result in its deletion + { + tmp_tip -= blocks_per_file - 1; + (blocks_per_file - 1, Some(tmp_tip), initial_file_count - files_per_range) + }, + // Case 3: Pruning more headers than a single file has (tip reduced by + // blocks_per_file + 1) should result in a file set deletion + { + tmp_tip -= blocks_per_file + 1; + (blocks_per_file + 1, Some(tmp_tip), initial_file_count - files_per_range * 2) + }, + // Case 4: Pruning all remaining headers from the file except the genesis header + { + ( + tmp_tip, + Some(0), // Only genesis block remains + files_per_range + 1, // The file set with block 0 should remain + ) + }, + // Case 5: Pruning the genesis header (should not delete the file set with block 0) + { + ( + 1, + None, // No blocks left + files_per_range + 1, // The file set with block 0 remains + ) + }, + ]; + + // Test cases execution + { + let sf_rw = StaticFileProvider::read_write(&static_dir) + .expect("Failed to create static file provider") + .with_custom_blocks_per_file(blocks_per_file); + + assert_eq!(sf_rw.get_highest_static_file_block(StaticFileSegment::Headers), Some(tip)); + assert_eq!( + fs::read_dir(static_dir.as_ref()).unwrap().count(), + initial_file_count as usize + ); + + let mut header_writer = sf_rw.latest_writer(StaticFileSegment::Headers).unwrap(); + + for (prune_count, expected_tip, expected_file_count) in test_cases { + prune_and_validate( + &mut header_writer, + &sf_rw, + &static_dir, + prune_count, + expected_tip, + expected_file_count, + ); + } + } + } } From 2295a2984658780f5fb882415982c4918d23fc87 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Thu, 19 Sep 2024 16:50:31 +0100 Subject: [PATCH 06/14] set new writer as dirty during pruning --- crates/storage/nippy-jar/src/writer.rs | 5 +++++ crates/storage/provider/src/providers/static_file/writer.rs | 1 + 2 files changed, 6 insertions(+) diff --git a/crates/storage/nippy-jar/src/writer.rs b/crates/storage/nippy-jar/src/writer.rs index 34272a9abd04..9bf9bf526448 100644 --- a/crates/storage/nippy-jar/src/writer.rs +++ b/crates/storage/nippy-jar/src/writer.rs @@ -108,6 +108,11 @@ impl NippyJarWriter { self.dirty } + /// Sets writer as dirty. + pub fn set_dirty(&mut self) { + self.dirty = true + } + /// Gets total writer rows in jar. pub const fn rows(&self) -> usize { self.jar.rows() diff --git a/crates/storage/provider/src/providers/static_file/writer.rs b/crates/storage/provider/src/providers/static_file/writer.rs index 9cd80fff8acc..b62fc22c730a 100644 --- a/crates/storage/provider/src/providers/static_file/writer.rs +++ b/crates/storage/provider/src/providers/static_file/writer.rs @@ -453,6 +453,7 @@ impl StaticFileProviderRW { self.metrics.clone(), )?; self.writer = previous_writer; + self.writer.set_dirty(); self.data_path = data_path; NippyJar::::load(¤t_path) .map_err(|e| ProviderError::NippyJar(e.to_string()))? From 6a8867af892ebec203afa3c18d62b5a93b2911ac Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Fri, 20 Sep 2024 11:01:39 +0100 Subject: [PATCH 07/14] add test_tx_based_truncation test --- .../provider/src/providers/static_file/mod.rs | 164 +++++++++++++++++- 1 file changed, 161 insertions(+), 3 deletions(-) diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index 7f423e0fbabe..96c2108332b7 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -64,11 +64,11 @@ mod tests { }; use reth_db_api::transaction::DbTxMut; use reth_primitives::{ - static_file::{find_fixed_range, DEFAULT_BLOCKS_PER_STATIC_FILE}, - BlockHash, Header, + static_file::{find_fixed_range, SegmentRangeInclusive, DEFAULT_BLOCKS_PER_STATIC_FILE}, + BlockHash, Header, Receipt, TransactionSignedNoHash, }; use reth_testing_utils::generators::{self, random_header_range}; - use std::{fs, path::Path}; + use std::{fs, ops::Range, path::Path}; #[test] fn test_snap() { @@ -266,4 +266,162 @@ mod tests { } } } + + /// 3 block ranges are built + /// + /// for `blocks_per_file = 10`: + /// * `0..=9` : except genesis, every block has a tx/receipt + /// * `10..=19`: no txs/receipts + /// * `20..=29`: only one tx/receipt + fn setup_tx_based_scenario( + sf_rw: &StaticFileProvider, + segment: StaticFileSegment, + blocks_per_file: u64, + ) { + fn setup_block_ranges( + writer: &mut StaticFileProviderRWRefMut<'_>, + sf_rw: &StaticFileProvider, + segment: StaticFileSegment, + block_range: &Range, + mut tx_count: u64, + next_tx_num: &mut u64, + ) { + for block in block_range.clone() { + writer.increment_block(block).unwrap(); + + // Append transaction/receipt if there's still a transaction count to append + if tx_count > 0 { + if segment.is_receipts() { + writer.append_receipt(*next_tx_num, &Receipt::default()).unwrap(); + } else { + writer + .append_transaction(*next_tx_num, &TransactionSignedNoHash::default()) + .unwrap(); + } + *next_tx_num += 1; + tx_count -= 1; + } + } + writer.commit().unwrap(); + + // Calculate expected values based on the range and transactions + let expected_block = block_range.end - 1; + let expected_tx = if tx_count == 0 { *next_tx_num - 1 } else { *next_tx_num }; + + // Perform assertions after processing the blocks + assert_eq!(sf_rw.get_highest_static_file_block(segment), Some(expected_block),); + assert_eq!(sf_rw.get_highest_static_file_tx(segment), Some(expected_tx),); + } + + // Define the block ranges and transaction counts as vectors + let block_ranges = vec![ + 0..blocks_per_file, + blocks_per_file..blocks_per_file * 2, + blocks_per_file * 2..blocks_per_file * 3, + ]; + + let tx_counts = vec![ + blocks_per_file - 1, // First range: tx per block except genesis + 0, // Second range: no transactions + 1, // Third range: 1 transaction in the second block + ]; + + let mut writer = sf_rw.latest_writer(segment).unwrap(); + let mut next_tx_num = 0; + + // Loop through setup scenarios + for (block_range, tx_count) in block_ranges.iter().zip(tx_counts.iter()) { + setup_block_ranges( + &mut writer, + sf_rw, + segment, + block_range, + *tx_count, + &mut next_tx_num, + ); + } + + // Ensure that scenario was properly setup + let expected_tx_ranges = vec![ + Some(SegmentRangeInclusive::new(0, 8)), + None, + Some(SegmentRangeInclusive::new(9, 9)), + ]; + + block_ranges.iter().zip(expected_tx_ranges).for_each(|(block_range, expected_tx_range)| { + assert_eq!( + sf_rw + .get_segment_provider_from_block(segment, block_range.start, None) + .unwrap() + .user_header() + .tx_range(), + expected_tx_range.as_ref() + ); + }); + } + + #[test] + #[ignore] + fn test_tx_based_truncation() { + let segments = [StaticFileSegment::Transactions, StaticFileSegment::Receipts]; + let blocks_per_file = 10; // Number of headers per file + let files_per_range = 3; // Number of files per range (data/conf/offset files) + let file_set_count = 3; // Number of sets of files to create + let initial_file_count = files_per_range * file_set_count + 1; // Includes lockfile + + for segment in segments { + let (static_dir, _) = create_test_static_files_dir(); + + let sf_rw = StaticFileProvider::read_write(&static_dir) + .expect("Failed to create static file provider") + .with_custom_blocks_per_file(blocks_per_file); + + setup_tx_based_scenario(&sf_rw, segment, blocks_per_file); + + let sf_rw = StaticFileProvider::read_write(&static_dir) + .expect("Failed to create static file provider") + .with_custom_blocks_per_file(blocks_per_file); + let highest_tx = sf_rw.get_highest_static_file_tx(segment).unwrap(); + + // Test cases + // [prune_count, last_block, expected_tx_tip, expected_file_count) + let test_cases = vec![ + // Case 1: 20..=29 has only one tx. Prune the only tx of the block range. + // It ensures that the file is not deleted even though there are no rows, since the + // `last_block` which is passed to the prune method is the first + // block of the range. + (1, blocks_per_file * 2, highest_tx - 1, initial_file_count), + // Case 2: 10..=19 has no txs. There are no txes in the whole block range, but want to unwind to block 9. + // Ensures that the 20..=29 and 10..=19 files are deleted. + (0, blocks_per_file - 1, highest_tx - 1, files_per_range + 1), // includes lockfile + // Case 3: Prune most txs up to block 1. + (7, 1, 1, files_per_range + 1), + // Case 4: Prune remaining tx and ensure that file is not deleted. + (1, 0, 0, files_per_range + 1), + ]; + + // Loop through test cases + for (prune_count, last_block, expected_tx_tip, expected_file_count) in test_cases { + let mut writer = sf_rw.latest_writer(segment).unwrap(); + + // Prune transactions or receipts based on the segment type + if segment.is_receipts() { + writer.prune_receipts(prune_count, last_block).unwrap(); + } else { + writer.prune_transactions(prune_count, last_block).unwrap(); + } + writer.commit().unwrap(); + + // Verify the highest block and transaction tips + assert_eq!(sf_rw.get_highest_static_file_block(segment), Some(last_block)); + assert_eq!(sf_rw.get_highest_static_file_tx(segment), Some(expected_tx_tip)); + + // Ensure the file count has reduced as expected + assert_eq!( + fs::read_dir(&static_dir).unwrap().count(), + expected_file_count as usize + ); + } + } + } } From 2093798e0368d9e67fb247c5261da1071abfbef2 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Fri, 20 Sep 2024 11:10:10 +0100 Subject: [PATCH 08/14] clippy --- crates/storage/provider/src/providers/static_file/mod.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index 96c2108332b7..e5e1b1e9b326 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -314,13 +314,13 @@ mod tests { } // Define the block ranges and transaction counts as vectors - let block_ranges = vec![ + let block_ranges = [ 0..blocks_per_file, blocks_per_file..blocks_per_file * 2, blocks_per_file * 2..blocks_per_file * 3, ]; - let tx_counts = vec![ + let tx_counts = [ blocks_per_file - 1, // First range: tx per block except genesis 0, // Second range: no transactions 1, // Third range: 1 transaction in the second block @@ -391,8 +391,9 @@ mod tests { // `last_block` which is passed to the prune method is the first // block of the range. (1, blocks_per_file * 2, highest_tx - 1, initial_file_count), - // Case 2: 10..=19 has no txs. There are no txes in the whole block range, but want to unwind to block 9. - // Ensures that the 20..=29 and 10..=19 files are deleted. + // Case 2: 10..=19 has no txs. There are no txes in the whole block range, but want + // to unwind to block 9. Ensures that the 20..=29 and 10..=19 files + // are deleted. (0, blocks_per_file - 1, highest_tx - 1, files_per_range + 1), // includes lockfile // Case 3: Prune most txs up to block 1. (7, 1, 1, files_per_range + 1), From bbe6c81b832797a66fc82d2d4c3ccb4ef5d9a8a9 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Fri, 20 Sep 2024 11:31:52 +0100 Subject: [PATCH 09/14] better test case err report --- .../provider/src/providers/static_file/mod.rs | 120 +++++++++++++----- 1 file changed, 85 insertions(+), 35 deletions(-) diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index e5e1b1e9b326..302cdbdf8895 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -68,7 +68,14 @@ mod tests { BlockHash, Header, Receipt, TransactionSignedNoHash, }; use reth_testing_utils::generators::{self, random_header_range}; - use std::{fs, ops::Range, path::Path}; + use std::{fmt::Debug, fs, ops::Range, path::Path}; + + fn assert_eyre(got: T, expected: T, msg: &str) -> eyre::Result<()> { + if got != expected { + eyre::bail!("{msg} | got: {got:?} expected: {expected:?})"); + } + Ok(()) + } #[test] fn test_snap() { @@ -186,18 +193,25 @@ mod tests { prune_count: u64, expected_tip: Option, expected_file_count: u64, - ) { - writer.prune_headers(prune_count).unwrap(); - writer.commit().unwrap(); + ) -> eyre::Result<()> { + writer.prune_headers(prune_count)?; + writer.commit()?; // Validate the highest block after pruning - assert_eq!( + assert_eyre( sf_rw.get_highest_static_file_block(StaticFileSegment::Headers), - expected_tip - ); + expected_tip, + "mismatch tip", + )?; // Validate the number of files remaining in the directory - assert_eq!(fs::read_dir(static_dir).unwrap().count(), expected_file_count as usize); + assert_eyre( + fs::read_dir(static_dir)?.count(), + expected_file_count as usize, + "mismatch file count", + )?; + + Ok(()) } // [ Test Cases ] @@ -206,23 +220,23 @@ mod tests { type ExpectedFileCount = u64; let mut tmp_tip = tip; let test_cases: Vec<(PruneCount, Option, ExpectedFileCount)> = vec![ - // Case 1: Pruning 1 header + // Case 0: Pruning 1 header { tmp_tip -= 1; (1, Some(tmp_tip), initial_file_count) }, - // Case 2: Pruning remaining rows from file should result in its deletion + // Case 1: Pruning remaining rows from file should result in its deletion { tmp_tip -= blocks_per_file - 1; (blocks_per_file - 1, Some(tmp_tip), initial_file_count - files_per_range) }, - // Case 3: Pruning more headers than a single file has (tip reduced by + // Case 2: Pruning more headers than a single file has (tip reduced by // blocks_per_file + 1) should result in a file set deletion { tmp_tip -= blocks_per_file + 1; (blocks_per_file + 1, Some(tmp_tip), initial_file_count - files_per_range * 2) }, - // Case 4: Pruning all remaining headers from the file except the genesis header + // Case 3: Pruning all remaining headers from the file except the genesis header { ( tmp_tip, @@ -230,7 +244,7 @@ mod tests { files_per_range + 1, // The file set with block 0 should remain ) }, - // Case 5: Pruning the genesis header (should not delete the file set with block 0) + // Case 4: Pruning the genesis header (should not delete the file set with block 0) { ( 1, @@ -254,7 +268,9 @@ mod tests { let mut header_writer = sf_rw.latest_writer(StaticFileSegment::Headers).unwrap(); - for (prune_count, expected_tip, expected_file_count) in test_cases { + for (case, (prune_count, expected_tip, expected_file_count)) in + test_cases.into_iter().enumerate() + { prune_and_validate( &mut header_writer, &sf_rw, @@ -262,7 +278,9 @@ mod tests { prune_count, expected_tip, expected_file_count, - ); + ) + .map_err(|err| eyre::eyre!("Test case {case}: {err}")) + .unwrap(); } } } @@ -369,6 +387,46 @@ mod tests { let file_set_count = 3; // Number of sets of files to create let initial_file_count = files_per_range * file_set_count + 1; // Includes lockfile + fn prune_and_validate( + static_dir: &tempfile::TempDir, + sf_rw: &StaticFileProvider, + segment: StaticFileSegment, + prune_count: u64, + last_block: u64, + expected_tx_tip: u64, + expected_file_count: i32, + ) -> eyre::Result<()> { + let mut writer = sf_rw.latest_writer(segment)?; + + // Prune transactions or receipts based on the segment type + if segment.is_receipts() { + writer.prune_receipts(prune_count, last_block)?; + } else { + writer.prune_transactions(prune_count, last_block)?; + } + writer.commit()?; + + // Verify the highest block and transaction tips + assert_eyre( + sf_rw.get_highest_static_file_block(segment), + Some(last_block), + "mismatch block", + )?; + assert_eyre( + sf_rw.get_highest_static_file_tx(segment), + Some(expected_tx_tip), + "mismatch tx", + )?; + + // Ensure the file count has reduced as expected + assert_eyre( + fs::read_dir(&static_dir)?.count(), + expected_file_count as usize, + "mismatch file count", + )?; + Ok(()) + } + for segment in segments { let (static_dir, _) = create_test_static_files_dir(); @@ -402,26 +460,18 @@ mod tests { ]; // Loop through test cases - for (prune_count, last_block, expected_tx_tip, expected_file_count) in test_cases { - let mut writer = sf_rw.latest_writer(segment).unwrap(); - - // Prune transactions or receipts based on the segment type - if segment.is_receipts() { - writer.prune_receipts(prune_count, last_block).unwrap(); - } else { - writer.prune_transactions(prune_count, last_block).unwrap(); - } - writer.commit().unwrap(); - - // Verify the highest block and transaction tips - assert_eq!(sf_rw.get_highest_static_file_block(segment), Some(last_block)); - assert_eq!(sf_rw.get_highest_static_file_tx(segment), Some(expected_tx_tip)); - - // Ensure the file count has reduced as expected - assert_eq!( - fs::read_dir(&static_dir).unwrap().count(), - expected_file_count as usize - ); + for (case, (prune_count, last_block, expected_tx_tip, expected_file_count)) in test_cases.into_iter().enumerate() { + prune_and_validate( + &static_dir, + &sf_rw, + segment, + prune_count, + last_block, + expected_tx_tip, + expected_file_count, + ) + .map_err(|err| eyre::eyre!("Test case {case}: {err}")) + .unwrap(); } } } From 93a4de77b87023e7934a9f2ccc3594fc40e89cde Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Fri, 20 Sep 2024 11:39:16 +0100 Subject: [PATCH 10/14] rename cases to 0 index --- crates/storage/provider/src/providers/static_file/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index 302cdbdf8895..ae1c2753a0b4 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -444,18 +444,18 @@ mod tests { // Test cases // [prune_count, last_block, expected_tx_tip, expected_file_count) let test_cases = vec![ - // Case 1: 20..=29 has only one tx. Prune the only tx of the block range. + // Case 0: 20..=29 has only one tx. Prune the only tx of the block range. // It ensures that the file is not deleted even though there are no rows, since the // `last_block` which is passed to the prune method is the first // block of the range. (1, blocks_per_file * 2, highest_tx - 1, initial_file_count), - // Case 2: 10..=19 has no txs. There are no txes in the whole block range, but want + // Case 1: 10..=19 has no txs. There are no txes in the whole block range, but want // to unwind to block 9. Ensures that the 20..=29 and 10..=19 files // are deleted. (0, blocks_per_file - 1, highest_tx - 1, files_per_range + 1), // includes lockfile - // Case 3: Prune most txs up to block 1. + // Case 2: Prune most txs up to block 1. (7, 1, 1, files_per_range + 1), - // Case 4: Prune remaining tx and ensure that file is not deleted. + // Case 3: Prune remaining tx and ensure that file is not deleted. (1, 0, 0, files_per_range + 1), ]; From 95583669b6c6bb619fd27f3753171c012407bdb4 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Fri, 20 Sep 2024 11:40:11 +0100 Subject: [PATCH 11/14] fmt --- crates/storage/provider/src/providers/static_file/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index ae1c2753a0b4..edf2a72a437b 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -460,7 +460,9 @@ mod tests { ]; // Loop through test cases - for (case, (prune_count, last_block, expected_tx_tip, expected_file_count)) in test_cases.into_iter().enumerate() { + for (case, (prune_count, last_block, expected_tx_tip, expected_file_count)) in + test_cases.into_iter().enumerate() + { prune_and_validate( &static_dir, &sf_rw, From 3a3ea58a74901366c830a8da49ef08deb95fcc78 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Fri, 20 Sep 2024 11:46:07 +0100 Subject: [PATCH 12/14] clippy --- crates/storage/provider/src/providers/static_file/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index edf2a72a437b..d62b1c685a05 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -388,8 +388,8 @@ mod tests { let initial_file_count = files_per_range * file_set_count + 1; // Includes lockfile fn prune_and_validate( - static_dir: &tempfile::TempDir, sf_rw: &StaticFileProvider, + static_dir: impl AsRef, segment: StaticFileSegment, prune_count: u64, last_block: u64, @@ -420,7 +420,7 @@ mod tests { // Ensure the file count has reduced as expected assert_eyre( - fs::read_dir(&static_dir)?.count(), + fs::read_dir(static_dir)?.count(), expected_file_count as usize, "mismatch file count", )?; @@ -464,8 +464,8 @@ mod tests { test_cases.into_iter().enumerate() { prune_and_validate( - &static_dir, &sf_rw, + &static_dir, segment, prune_count, last_block, From 6b525756cb14ace310243c395df0726826b11fae Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Fri, 20 Sep 2024 12:10:35 +0100 Subject: [PATCH 13/14] err msg --- .../storage/provider/src/providers/static_file/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index d62b1c685a05..e6c297db7ab3 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -201,14 +201,14 @@ mod tests { assert_eyre( sf_rw.get_highest_static_file_block(StaticFileSegment::Headers), expected_tip, - "mismatch tip", + "block mismatch", )?; // Validate the number of files remaining in the directory assert_eyre( fs::read_dir(static_dir)?.count(), expected_file_count as usize, - "mismatch file count", + "file count mismatch", )?; Ok(()) @@ -410,19 +410,19 @@ mod tests { assert_eyre( sf_rw.get_highest_static_file_block(segment), Some(last_block), - "mismatch block", + "block mismatch", )?; assert_eyre( sf_rw.get_highest_static_file_tx(segment), Some(expected_tx_tip), - "mismatch tx", + "tx mismatch", )?; // Ensure the file count has reduced as expected assert_eyre( fs::read_dir(static_dir)?.count(), expected_file_count as usize, - "mismatch file count", + "file count mismatch", )?; Ok(()) } From c7ae0981b85fb0df82fff43064451c9cb0a69829 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Fri, 20 Sep 2024 12:12:36 +0100 Subject: [PATCH 14/14] typo --- crates/storage/provider/src/providers/static_file/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/storage/provider/src/providers/static_file/mod.rs b/crates/storage/provider/src/providers/static_file/mod.rs index e6c297db7ab3..8152dd0ed9ca 100644 --- a/crates/storage/provider/src/providers/static_file/mod.rs +++ b/crates/storage/provider/src/providers/static_file/mod.rs @@ -382,7 +382,7 @@ mod tests { #[ignore] fn test_tx_based_truncation() { let segments = [StaticFileSegment::Transactions, StaticFileSegment::Receipts]; - let blocks_per_file = 10; // Number of headers per file + let blocks_per_file = 10; // Number of blocks per file let files_per_range = 3; // Number of files per range (data/conf/offset files) let file_set_count = 3; // Number of sets of files to create let initial_file_count = files_per_range * file_set_count + 1; // Includes lockfile