From e72e85632b33457798e7c9d58ed68a32e013e0c1 Mon Sep 17 00:00:00 2001 From: Georgios Konstantopoulos Date: Fri, 6 Feb 2026 20:33:31 -0800 Subject: [PATCH] perf(persistence): combine save_blocks and prune into single MDBX commit (#21927) Co-authored-by: Amp Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> --- crates/engine/tree/src/persistence.rs | 29 +++++++++------------------ 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/crates/engine/tree/src/persistence.rs b/crates/engine/tree/src/persistence.rs index f6c81999aa..cb7994d9c5 100644 --- a/crates/engine/tree/src/persistence.rs +++ b/crates/engine/tree/src/persistence.rs @@ -9,7 +9,7 @@ use reth_provider::{ providers::ProviderNodeTypes, BlockExecutionWriter, BlockHashReader, ChainStateBlockWriter, DBProvider, DatabaseProviderFactory, ProviderFactory, SaveBlocksMode, }; -use reth_prune::{PrunerError, PrunerOutput, PrunerWithFactory}; +use reth_prune::{PrunerError, PrunerWithFactory}; use reth_stages_api::{MetricEvent, MetricEventsSender}; use reth_tasks::spawn_os_thread; use std::{ @@ -74,17 +74,6 @@ where pending_safe_block: None, } } - - /// Prunes block data before the given block number according to the configured prune - /// configuration. - #[instrument(level = "debug", target = "engine::persistence", skip_all, fields(block_num))] - fn prune_before(&mut self, block_num: u64) -> Result { - debug!(target: "engine::persistence", ?block_num, "Running pruner"); - let start_time = Instant::now(); - let result = self.pruner.run(block_num); - self.metrics.prune_before_duration_seconds.record(start_time.elapsed()); - result - } } impl PersistenceService @@ -117,11 +106,6 @@ where let _ = self .sync_metrics_tx .send(MetricEvent::SyncHeight { height: block_number }); - - if self.pruner.is_pruning_needed(block_number) { - // We log `PrunerOutput` inside the `Pruner` - let _ = self.prune_before(block_number)?; - } } } PersistenceAction::SaveFinalizedBlock(finalized_block) => { @@ -162,7 +146,6 @@ where let last_block = blocks.last().map(|b| b.recovered_block.num_hash()); let block_count = blocks.len(); - // Take any pending finalized/safe block updates to commit together let pending_finalized = self.pending_finalized_block.take(); let pending_safe = self.pending_safe_block.take(); @@ -170,11 +153,10 @@ where let start_time = Instant::now(); - if last_block.is_some() { + if let Some(last) = last_block { let provider_rw = self.provider.database_provider_rw()?; provider_rw.save_blocks(blocks, SaveBlocksMode::Full)?; - // Commit pending finalized/safe block updates in the same transaction if let Some(finalized) = pending_finalized { provider_rw.save_finalized_block_number(finalized)?; } @@ -182,6 +164,13 @@ where provider_rw.save_safe_block_number(safe)?; } + if self.pruner.is_pruning_needed(last.number) { + debug!(target: "engine::persistence", block_num=?last.number, "Running pruner"); + let prune_start = Instant::now(); + let _ = self.pruner.run_with_provider(&provider_rw, last.number)?; + self.metrics.prune_before_duration_seconds.record(prune_start.elapsed()); + } + provider_rw.commit()?; }