mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-04-30 03:01:58 -04:00
refactor(provider): extract heal_segment for NippyJar consistency (#20508)
This commit is contained in:
@@ -1084,31 +1084,13 @@ impl<N: NodePrimitives> StaticFileProvider<N> {
|
||||
}
|
||||
}
|
||||
|
||||
let initial_highest_block = self.get_highest_static_file_block(segment);
|
||||
debug!(target: "reth::providers::static_file", ?segment, ?initial_highest_block, "Initial highest block for segment");
|
||||
|
||||
// File consistency is broken if:
|
||||
//
|
||||
// * appending data was interrupted before a config commit, then data file will be
|
||||
// truncated according to the config.
|
||||
//
|
||||
// * pruning data was interrupted before a config commit, then we have deleted data that
|
||||
// we are expected to still have. We need to check the Database and unwind everything
|
||||
// accordingly.
|
||||
if self.access.is_read_only() {
|
||||
debug!(target: "reth::providers::static_file", ?segment, "Checking segment consistency (read-only)");
|
||||
self.check_segment_consistency(segment)?;
|
||||
} else {
|
||||
debug!(target: "reth::providers::static_file", ?segment, "Fetching latest writer which might heal any potential inconsistency");
|
||||
// Fetching the writer will attempt to heal any file level inconsistency.
|
||||
self.latest_writer(segment)?;
|
||||
}
|
||||
// Heal file-level inconsistencies and get before/after highest block
|
||||
let (initial_highest_block, mut highest_block) = self.maybe_heal_segment(segment)?;
|
||||
|
||||
// Only applies to block-based static files. (Headers)
|
||||
//
|
||||
// The updated `highest_block` may have decreased if we healed from a pruning
|
||||
// interruption.
|
||||
let mut highest_block = self.get_highest_static_file_block(segment);
|
||||
if initial_highest_block != highest_block {
|
||||
info!(
|
||||
target: "reth::providers::static_file",
|
||||
@@ -1223,6 +1205,47 @@ impl<N: NodePrimitives> StaticFileProvider<N> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Attempts to heal file-level (`NippyJar`) inconsistencies for a single static file segment.
|
||||
///
|
||||
/// Returns the highest block before and after healing, which can be used to detect
|
||||
/// if healing from a pruning interruption decreased the highest block.
|
||||
///
|
||||
/// File consistency is broken if:
|
||||
///
|
||||
/// * appending data was interrupted before a config commit, then data file will be truncated
|
||||
/// according to the config.
|
||||
///
|
||||
/// * pruning data was interrupted before a config commit, then we have deleted data that we are
|
||||
/// expected to still have. We need to check the Database and unwind everything accordingly.
|
||||
///
|
||||
/// **Note:** In read-only mode, this will return an error if a consistency issue is detected,
|
||||
/// since healing requires write access.
|
||||
fn maybe_heal_segment(
|
||||
&self,
|
||||
segment: StaticFileSegment,
|
||||
) -> ProviderResult<(Option<BlockNumber>, Option<BlockNumber>)> {
|
||||
let initial_highest_block = self.get_highest_static_file_block(segment);
|
||||
debug!(target: "reth::providers::static_file", ?segment, ?initial_highest_block, "Initial highest block for segment");
|
||||
|
||||
if self.access.is_read_only() {
|
||||
// Read-only mode: cannot modify files, so just validate consistency and error if
|
||||
// broken.
|
||||
debug!(target: "reth::providers::static_file", ?segment, "Checking segment consistency (read-only)");
|
||||
self.check_segment_consistency(segment)?;
|
||||
} else {
|
||||
// Writable mode: fetching the writer will automatically heal any file-level
|
||||
// inconsistency by truncating data to match the last committed config.
|
||||
debug!(target: "reth::providers::static_file", ?segment, "Fetching latest writer which might heal any potential inconsistency");
|
||||
self.latest_writer(segment)?;
|
||||
}
|
||||
|
||||
// The updated `highest_block` may have decreased if we healed from a pruning
|
||||
// interruption.
|
||||
let highest_block = self.get_highest_static_file_block(segment);
|
||||
|
||||
Ok((initial_highest_block, highest_block))
|
||||
}
|
||||
|
||||
/// Check invariants for each corresponding table and static file segment:
|
||||
///
|
||||
/// * the corresponding database table should overlap or have continuity in their keys
|
||||
|
||||
Reference in New Issue
Block a user