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 RocksDBProviderFactory, StageCheckpointReader, StaticFileProviderFactory,
11};
12use reth_prune_types::PruneModes;
13use reth_storage_api::{ChangeSetReader, StorageChangeSetReader, StorageSettingsCache};
14use std::time::Duration;
15use tokio::sync::watch;
16
17#[derive(Debug, Clone)]
19pub struct PrunerBuilder {
20 block_interval: usize,
22 segments: PruneModes,
24 delete_limit: usize,
26 timeout: Option<Duration>,
28 finished_exex_height: watch::Receiver<FinishedExExHeight>,
30}
31
32impl PrunerBuilder {
33 pub fn new(pruner_config: PruneConfig) -> Self {
35 Self::default()
36 .block_interval(pruner_config.block_interval)
37 .segments(pruner_config.segments)
38 }
39
40 pub const fn block_interval(mut self, block_interval: usize) -> Self {
42 self.block_interval = block_interval;
43 self
44 }
45
46 pub fn segments(mut self, segments: PruneModes) -> Self {
48 self.segments = segments;
49 self
50 }
51
52 pub const fn delete_limit(mut self, prune_delete_limit: usize) -> Self {
54 self.delete_limit = prune_delete_limit;
55 self
56 }
57
58 pub const fn timeout(mut self, timeout: Duration) -> Self {
63 self.timeout = Some(timeout);
64 self
65 }
66
67 pub fn finished_exex_height(
69 mut self,
70 finished_exex_height: watch::Receiver<FinishedExExHeight>,
71 ) -> Self {
72 self.finished_exex_height = finished_exex_height;
73 self
74 }
75
76 pub fn build_with_provider_factory<PF>(self, provider_factory: PF) -> Pruner<PF::ProviderRW, PF>
78 where
79 PF: DatabaseProviderFactory<
80 ProviderRW: PruneCheckpointWriter
81 + PruneCheckpointReader
82 + BlockReader<Transaction: Encodable2718>
83 + ChainStateBlockReader
84 + StorageSettingsCache
85 + StageCheckpointReader
86 + ChangeSetReader
87 + StorageChangeSetReader
88 + RocksDBProviderFactory
89 + StaticFileProviderFactory<
90 Primitives: NodePrimitives<SignedTx: Value, Receipt: Value, BlockHeader: Value>,
91 >,
92 > + StaticFileProviderFactory<
93 Primitives = <PF::ProviderRW as NodePrimitivesProvider>::Primitives,
94 >,
95 {
96 let segments =
97 SegmentSet::from_components(provider_factory.static_file_provider(), self.segments);
98
99 Pruner::new_with_factory(
100 provider_factory,
101 segments.into_vec(),
102 self.block_interval,
103 self.delete_limit,
104 self.timeout,
105 self.finished_exex_height,
106 )
107 }
108
109 pub fn build<Provider>(
111 self,
112 static_file_provider: StaticFileProvider<Provider::Primitives>,
113 ) -> Pruner<Provider, ()>
114 where
115 Provider: StaticFileProviderFactory<
116 Primitives: NodePrimitives<SignedTx: Value, Receipt: Value, BlockHeader: Value>,
117 > + DBProvider<Tx: DbTxMut>
118 + BlockReader<Transaction: Encodable2718>
119 + ChainStateBlockReader
120 + PruneCheckpointWriter
121 + PruneCheckpointReader
122 + StorageSettingsCache
123 + StageCheckpointReader
124 + ChangeSetReader
125 + StorageChangeSetReader
126 + RocksDBProviderFactory,
127 {
128 let segments = SegmentSet::<Provider>::from_components(static_file_provider, self.segments);
129
130 Pruner::new(
131 segments.into_vec(),
132 self.block_interval,
133 self.delete_limit,
134 self.timeout,
135 self.finished_exex_height,
136 )
137 }
138}
139
140impl Default for PrunerBuilder {
141 fn default() -> Self {
142 Self {
143 block_interval: 5,
144 segments: PruneModes::default(),
145 delete_limit: usize::MAX,
146 timeout: None,
147 finished_exex_height: watch::channel(FinishedExExHeight::NoExExs).1,
148 }
149 }
150}