fix(prune): reth prune requires being run twice to actually prune (#21785)

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
YK
2026-02-05 11:08:49 +08:00
committed by GitHub
parent 05ec479398
commit dfc54cf89f
3 changed files with 43 additions and 7 deletions

View File

@@ -100,12 +100,7 @@ impl<C: ChainSpecParser<ChainSpec: EthChainSpec + EthereumHardforks>> PruneComma
let batch_pruned: usize = output.segments.iter().map(|(_, seg)| seg.pruned).sum();
total_pruned = total_pruned.saturating_add(batch_pruned);
// Check if all segments are finished (not just the overall progress,
// since the pruner sets overall progress from the last segment only)
let all_segments_finished =
output.segments.iter().all(|(_, seg)| seg.progress.is_finished());
if all_segments_finished {
if output.progress.is_finished() {
info!(target: "reth::cli", total_pruned, "Pruned data from database");
break;
}

View File

@@ -177,6 +177,8 @@ where
for segment in &self.segments {
if limiter.is_limit_reached() {
output.progress =
output.progress.combine(PruneProgress::HasMoreData(limiter.interrupt_reason()));
break
}
@@ -233,7 +235,7 @@ where
.set(highest_pruned_block as f64);
}
output.progress = segment_output.progress;
output.progress = output.progress.combine(segment_output.progress);
output.segments.push((segment.segment(), segment_output));
debug!(

View File

@@ -165,4 +165,43 @@ impl PruneProgress {
pub const fn is_finished(&self) -> bool {
matches!(self, Self::Finished)
}
/// Combines two progress values, keeping `HasMoreData` if either has it.
///
/// Once any segment reports `HasMoreData`, the combined progress remains
/// `HasMoreData`. Only returns `Finished` if both are `Finished`.
#[must_use]
pub const fn combine(self, other: Self) -> Self {
match (self, other) {
(Self::HasMoreData(reason), _) => Self::HasMoreData(reason),
(Self::Finished, other) => other,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_prune_progress_combine() {
use PruneInterruptReason::*;
use PruneProgress::*;
// HasMoreData dominates Finished
assert!(matches!(HasMoreData(Timeout).combine(Finished), HasMoreData(Timeout)));
// First HasMoreData reason is preserved
assert!(matches!(
HasMoreData(Timeout).combine(HasMoreData(DeletedEntriesLimitReached)),
HasMoreData(Timeout)
));
// Finished adopts new progress
assert!(matches!(Finished.combine(Finished), Finished));
assert!(matches!(
Finished.combine(HasMoreData(DeletedEntriesLimitReached)),
HasMoreData(DeletedEntriesLimitReached)
));
}
}