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#[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 const 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 + 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 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}