diff --git a/crates/static-file/types/src/segment.rs b/crates/static-file/types/src/segment.rs index bc6d37ffc29b..889518ec6f04 100644 --- a/crates/static-file/types/src/segment.rs +++ b/crates/static-file/types/src/segment.rs @@ -23,21 +23,24 @@ use strum::{AsRefStr, EnumIter, EnumString}; )] #[cfg_attr(feature = "clap", derive(clap::ValueEnum))] /// Segment of the data that can be moved to static files. +/// +/// Order is important. Eg. `BlockBodyIndices` from `BlockBodyMeta` should be correct before +/// `Transactions` and `Receipts` can be checked. pub enum StaticFileSegment { #[strum(serialize = "headers")] /// Static File segment responsible for the `CanonicalHeaders`, `Headers`, /// `HeaderTerminalDifficulties` tables. Headers, + #[strum(serialize = "bmeta")] + /// Static File segment responsible for the `BlockBodyIndices`, `BlockOmmers`, + /// `BlockWithdrawals` tables. + BlockMeta, #[strum(serialize = "transactions")] /// Static File segment responsible for the `Transactions` table. Transactions, #[strum(serialize = "receipts")] /// Static File segment responsible for the `Receipts` table. Receipts, - #[strum(serialize = "bmeta")] - /// Static File segment responsible for the `BlockBodyIndices`, `BlockOmmers`, - /// `BlockWithdrawals` tables. - BlockMeta, } impl StaticFileSegment { @@ -47,7 +50,7 @@ impl StaticFileSegment { Self::Headers => "headers", Self::Transactions => "transactions", Self::Receipts => "receipts", - Self::BlockMeta => "blockmeta", + Self::BlockMeta => "bmeta", } } diff --git a/crates/storage/provider/src/providers/static_file/manager.rs b/crates/storage/provider/src/providers/static_file/manager.rs index 3c1d1d6ab2af..285c9d745f34 100644 --- a/crates/storage/provider/src/providers/static_file/manager.rs +++ b/crates/storage/provider/src/providers/static_file/manager.rs @@ -781,14 +781,13 @@ impl StaticFileProvider { highest_tx, highest_block, )?, - StaticFileSegment::BlockMeta => { - self.ensure_invariants::<_, tables::BlockBodyIndices>( + StaticFileSegment::BlockMeta => self + .ensure_invariants::<_, tables::BlockBodyIndices>( provider, segment, - highest_tx, highest_block, - )? - } + highest_block, + )?, } { update_unwind_target(unwind); } @@ -838,35 +837,39 @@ impl StaticFileProvider { where Provider: DBProvider + BlockReader + StageCheckpointReader, { - let highest_static_file_entry = highest_static_file_entry.unwrap_or_default(); - let highest_static_file_block = highest_static_file_block.unwrap_or_default(); let mut db_cursor = provider.tx_ref().cursor_read::()?; - if let Some((db_first_entry, _)) = db_cursor.first()? { - // If there is a gap between the entry found in static file and - // database, then we have most likely lost static file data and need to unwind so we can - // load it again - if !(db_first_entry <= highest_static_file_entry || - highest_static_file_entry + 1 == db_first_entry) + if let (Some(highest_entry), Some(highest_block)) = + (highest_static_file_entry, highest_static_file_block) { - info!( - target: "reth::providers::static_file", - ?db_first_entry, - ?highest_static_file_entry, - unwind_target = highest_static_file_block, - ?segment, - "Setting unwind target." - ); - return Ok(Some(highest_static_file_block)) + // If there is a gap between the entry found in static file and + // database, then we have most likely lost static file data and need to unwind so we + // can load it again + if !(db_first_entry <= highest_entry || highest_entry + 1 == db_first_entry) { + info!( + target: "reth::providers::static_file", + ?db_first_entry, + ?highest_entry, + unwind_target = highest_block, + ?segment, + "Setting unwind target." + ); + return Ok(Some(highest_block)) + } } if let Some((db_last_entry, _)) = db_cursor.last()? { - if db_last_entry > highest_static_file_entry { + if highest_static_file_entry + .is_none_or(|highest_entry| db_last_entry > highest_entry) + { return Ok(None) } } } + let highest_static_file_entry = highest_static_file_entry.unwrap_or_default(); + let highest_static_file_block = highest_static_file_block.unwrap_or_default(); + // If static file entry is ahead of the database entries, then ensure the checkpoint block // number matches. let checkpoint_block_number = provider @@ -906,6 +909,8 @@ impl StaticFileProvider { // TODO(joshie): is_block_meta writer.prune_headers(highest_static_file_block - checkpoint_block_number)?; } else if let Some(block) = provider.block_body_indices(checkpoint_block_number)? { + // todo joshie: is querying block_body_indices a potential issue once bbi is moved + // to sf as well let number = highest_static_file_entry - block.last_tx_num(); if segment.is_receipts() { writer.prune_receipts(number, checkpoint_block_number)?; diff --git a/crates/storage/provider/src/providers/static_file/writer.rs b/crates/storage/provider/src/providers/static_file/writer.rs index 67946975c085..9e281f40c72f 100644 --- a/crates/storage/provider/src/providers/static_file/writer.rs +++ b/crates/storage/provider/src/providers/static_file/writer.rs @@ -68,7 +68,7 @@ impl StaticFileWriters { } pub(crate) fn commit(&self) -> ProviderResult<()> { - for writer_lock in [&self.headers, &self.transactions, &self.receipts] { + for writer_lock in [&self.headers, &self.block_meta, &self.transactions, &self.receipts] { let mut writer = writer_lock.write(); if let Some(writer) = writer.as_mut() { writer.commit()?;