reth_prune/
builder.rs

1use crate::{segments::SegmentSet, Pruner};
2use alloy_eips::eip2718::Encodable2718;
3use reth_config::PruneConfig;
4use reth_db_api::{table::Value, transaction::DbTxMut};
5use reth_exex_types::FinishedExExHeight;
6use reth_primitives_traits::NodePrimitives;
7use reth_provider::{
8    providers::StaticFileProvider, BlockReader, ChainStateBlockReader, DBProvider,
9    DatabaseProviderFactory, NodePrimitivesProvider, PruneCheckpointReader, PruneCheckpointWriter,
10    StaticFileProviderFactory,
11};
12use reth_prune_types::PruneModes;
13use std::time::Duration;
14use tokio::sync::watch;
15
16/// Contains the information required to build a pruner
17#[derive(Debug, Clone)]
18pub struct PrunerBuilder {
19    /// Minimum pruning interval measured in blocks.
20    block_interval: usize,
21    /// Pruning configuration for every part of the data that can be pruned.
22    segments: PruneModes,
23    /// The delete limit for pruner, per run.
24    delete_limit: usize,
25    /// Time a pruner job can run before timing out.
26    timeout: Option<Duration>,
27    /// The finished height of all `ExEx`'s.
28    finished_exex_height: watch::Receiver<FinishedExExHeight>,
29}
30
31impl PrunerBuilder {
32    /// Creates a new [`PrunerBuilder`] from the given [`PruneConfig`].
33    pub fn new(pruner_config: PruneConfig) -> Self {
34        Self::default()
35            .block_interval(pruner_config.block_interval)
36            .segments(pruner_config.segments)
37    }
38
39    /// Sets the minimum pruning interval measured in blocks.
40    pub const fn block_interval(mut self, block_interval: usize) -> Self {
41        self.block_interval = block_interval;
42        self
43    }
44
45    /// Sets the configuration for every part of the data that can be pruned.
46    pub const fn segments(mut self, segments: PruneModes) -> Self {
47        self.segments = segments;
48        self
49    }
50
51    /// Sets the delete limit for pruner, per run.
52    pub const fn delete_limit(mut self, prune_delete_limit: usize) -> Self {
53        self.delete_limit = prune_delete_limit;
54        self
55    }
56
57    /// Sets the timeout for pruner, per run.
58    ///
59    /// CAUTION: Account and Storage History prune segments treat this timeout as a soft limit,
60    /// meaning they can go beyond it.
61    pub const fn timeout(mut self, timeout: Duration) -> Self {
62        self.timeout = Some(timeout);
63        self
64    }
65
66    /// Sets the receiver for the finished height of all `ExEx`'s.
67    pub fn finished_exex_height(
68        mut self,
69        finished_exex_height: watch::Receiver<FinishedExExHeight>,
70    ) -> Self {
71        self.finished_exex_height = finished_exex_height;
72        self
73    }
74
75    /// Builds a [Pruner] from the current configuration with the given provider factory.
76    pub fn build_with_provider_factory<PF>(self, provider_factory: PF) -> Pruner<PF::ProviderRW, PF>
77    where
78        PF: DatabaseProviderFactory<
79                ProviderRW: PruneCheckpointWriter
80                                + PruneCheckpointReader
81                                + BlockReader<Transaction: Encodable2718>
82                                + ChainStateBlockReader
83                                + StaticFileProviderFactory<
84                    Primitives: NodePrimitives<SignedTx: Value, Receipt: Value, BlockHeader: Value>,
85                >,
86            > + StaticFileProviderFactory<
87                Primitives = <PF::ProviderRW as NodePrimitivesProvider>::Primitives,
88            >,
89    {
90        let segments =
91            SegmentSet::from_components(provider_factory.static_file_provider(), self.segments);
92
93        Pruner::new_with_factory(
94            provider_factory,
95            segments.into_vec(),
96            self.block_interval,
97            self.delete_limit,
98            self.timeout,
99            self.finished_exex_height,
100        )
101    }
102
103    /// Builds a [Pruner] from the current configuration with the given static file provider.
104    pub fn build<Provider>(
105        self,
106        static_file_provider: StaticFileProvider<Provider::Primitives>,
107    ) -> Pruner<Provider, ()>
108    where
109        Provider: StaticFileProviderFactory<
110                Primitives: NodePrimitives<SignedTx: Value, Receipt: Value, BlockHeader: Value>,
111            > + DBProvider<Tx: DbTxMut>
112            + BlockReader<Transaction: Encodable2718>
113            + ChainStateBlockReader
114            + PruneCheckpointWriter
115            + PruneCheckpointReader,
116    {
117        let segments = SegmentSet::<Provider>::from_components(static_file_provider, self.segments);
118
119        Pruner::new(
120            segments.into_vec(),
121            self.block_interval,
122            self.delete_limit,
123            self.timeout,
124            self.finished_exex_height,
125        )
126    }
127}
128
129impl Default for PrunerBuilder {
130    fn default() -> Self {
131        Self {
132            block_interval: 5,
133            segments: PruneModes::default(),
134            delete_limit: usize::MAX,
135            timeout: None,
136            finished_exex_height: watch::channel(FinishedExExHeight::NoExExs).1,
137        }
138    }
139}