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 StageCheckpointReader, StaticFileProviderFactory, StorageSettingsCache,
11};
12use reth_prune_types::PruneModes;
13use std::time::Duration;
14use tokio::sync::watch;
15
16#[derive(Debug, Clone)]
18pub struct PrunerBuilder {
19 block_interval: usize,
21 segments: PruneModes,
23 delete_limit: usize,
25 timeout: Option<Duration>,
27 finished_exex_height: watch::Receiver<FinishedExExHeight>,
29}
30
31impl PrunerBuilder {
32 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 pub const fn block_interval(mut self, block_interval: usize) -> Self {
41 self.block_interval = block_interval;
42 self
43 }
44
45 pub fn segments(mut self, segments: PruneModes) -> Self {
47 self.segments = segments;
48 self
49 }
50
51 pub const fn delete_limit(mut self, prune_delete_limit: usize) -> Self {
53 self.delete_limit = prune_delete_limit;
54 self
55 }
56
57 pub const fn timeout(mut self, timeout: Duration) -> Self {
62 self.timeout = Some(timeout);
63 self
64 }
65
66 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 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 + StorageSettingsCache
84 + StageCheckpointReader
85 + StaticFileProviderFactory<
86 Primitives: NodePrimitives<SignedTx: Value, Receipt: Value, BlockHeader: Value>,
87 >,
88 > + StaticFileProviderFactory<
89 Primitives = <PF::ProviderRW as NodePrimitivesProvider>::Primitives,
90 >,
91 {
92 let segments =
93 SegmentSet::from_components(provider_factory.static_file_provider(), self.segments);
94
95 Pruner::new_with_factory(
96 provider_factory,
97 segments.into_vec(),
98 self.block_interval,
99 self.delete_limit,
100 self.timeout,
101 self.finished_exex_height,
102 )
103 }
104
105 pub fn build<Provider>(
107 self,
108 static_file_provider: StaticFileProvider<Provider::Primitives>,
109 ) -> Pruner<Provider, ()>
110 where
111 Provider: StaticFileProviderFactory<
112 Primitives: NodePrimitives<SignedTx: Value, Receipt: Value, BlockHeader: Value>,
113 > + DBProvider<Tx: DbTxMut>
114 + BlockReader<Transaction: Encodable2718>
115 + ChainStateBlockReader
116 + PruneCheckpointWriter
117 + PruneCheckpointReader
118 + StorageSettingsCache
119 + StageCheckpointReader,
120 {
121 let segments = SegmentSet::<Provider>::from_components(static_file_provider, self.segments);
122
123 Pruner::new(
124 segments.into_vec(),
125 self.block_interval,
126 self.delete_limit,
127 self.timeout,
128 self.finished_exex_height,
129 )
130 }
131}
132
133impl Default for PrunerBuilder {
134 fn default() -> Self {
135 Self {
136 block_interval: 5,
137 segments: PruneModes::default(),
138 delete_limit: usize::MAX,
139 timeout: None,
140 finished_exex_height: watch::channel(FinishedExExHeight::NoExExs).1,
141 }
142 }
143}