hotshot_query_service/data_source/storage/
pruning.rs1use std::{fmt::Debug, time::Duration};
14
15use anyhow::bail;
16use async_trait::async_trait;
17
18#[derive(Clone, Debug)]
19pub struct PrunerCfg {
20 pruning_threshold: Option<u64>,
21 minimum_retention: Duration,
22 target_retention: Duration,
23 state_minimum_retention: Duration,
24 state_target_retention: Duration,
25 batch_size: u64,
26 max_usage: u16,
27 interval: Duration,
28 incremental_vacuum_pages: u64,
29 state_tables: Vec<String>,
30}
31
32#[async_trait]
33pub trait PruneStorage: PrunerConfig {
34 type Pruner<'a>: Default + Send
35 where
36 Self: 'a;
37
38 async fn prune<'a>(&'a self, _pruner: &mut Self::Pruner<'a>) -> anyhow::Result<Option<u64>> {
39 Ok(None)
40 }
41}
42
43#[async_trait]
44pub trait PrunedHeightStorage: Sized {
45 async fn load_pruned_height(&mut self) -> anyhow::Result<Option<u64>> {
46 Ok(None)
47 }
48
49 async fn load_state_pruned_height(&mut self) -> anyhow::Result<Option<u64>> {
50 Ok(None)
51 }
52}
53
54#[async_trait]
55pub trait PrunedHeightDataSource: Sized {
56 async fn load_pruned_height(&self) -> anyhow::Result<Option<u64>> {
57 Ok(None)
58 }
59
60 async fn load_state_pruned_height(&self) -> anyhow::Result<Option<u64>> {
61 Ok(None)
62 }
63}
64
65pub trait PrunerConfig {
66 fn set_pruning_config(&mut self, _cfg: PrunerCfg) {}
67 fn get_pruning_config(&self) -> Option<PrunerCfg> {
68 None
69 }
70}
71
72impl PrunerCfg {
73 pub fn new() -> Self {
74 Default::default()
75 }
76
77 pub fn validate(&self) -> anyhow::Result<()> {
78 if let Some(pruning_threshold) = self.pruning_threshold
79 && pruning_threshold == 0
80 {
81 bail!("pruning_threshold must be greater than 0 or set to None")
82 }
83
84 if self.max_usage > 10000 {
85 bail!("max_usage must be less than or equal to 10000")
86 }
87
88 Ok(())
89 }
90
91 pub fn with_state_tables(mut self, state_tables: Vec<String>) -> Self {
92 self.state_tables = state_tables;
93 self
94 }
95
96 pub fn with_pruning_threshold(mut self, pruning_threshold: u64) -> Self {
97 self.pruning_threshold = Some(pruning_threshold);
98 self
99 }
100
101 pub fn with_minimum_retention(mut self, minimum_retention: Duration) -> Self {
102 self.minimum_retention = minimum_retention;
103 self
104 }
105
106 pub fn with_state_minimum_retention(mut self, state_minimum_retention: Duration) -> Self {
107 self.state_minimum_retention = state_minimum_retention;
108 self
109 }
110
111 pub fn with_target_retention(mut self, target_retention: Duration) -> Self {
112 self.target_retention = target_retention;
113 self
114 }
115
116 pub fn with_state_target_retention(mut self, state_target_retention: Duration) -> Self {
117 self.state_target_retention = state_target_retention;
118 self
119 }
120
121 pub fn with_batch_size(mut self, batch_size: u64) -> Self {
122 self.batch_size = batch_size;
123 self
124 }
125
126 pub fn with_max_usage(mut self, max_usage: u16) -> Self {
127 self.max_usage = max_usage;
128 self
129 }
130
131 pub fn with_interval(mut self, interval: Duration) -> Self {
132 self.interval = interval;
133 self
134 }
135
136 pub fn with_incremental_vacuum_pages(mut self, pages: u64) -> Self {
137 self.incremental_vacuum_pages = pages;
138 self
139 }
140
141 pub fn pruning_threshold(&self) -> Option<u64> {
147 self.pruning_threshold
148 }
149
150 pub fn minimum_retention(&self) -> Duration {
154 self.minimum_retention
155 }
156
157 pub fn target_retention(&self) -> Duration {
162 self.target_retention
163 }
164
165 pub fn state_minimum_retention(&self) -> Duration {
169 self.state_minimum_retention
170 }
171
172 pub fn state_target_retention(&self) -> Duration {
177 self.state_target_retention
178 }
179
180 pub fn batch_size(&self) -> u64 {
182 self.batch_size
183 }
184
185 pub fn max_usage(&self) -> u16 {
191 self.max_usage
192 }
193
194 pub fn interval(&self) -> Duration {
196 self.interval
197 }
198
199 pub fn incremental_vacuum_pages(&self) -> u64 {
201 self.incremental_vacuum_pages
202 }
203
204 pub fn state_tables(&self) -> &[String] {
206 &self.state_tables
207 }
208}
209
210impl Default for PrunerCfg {
211 fn default() -> Self {
212 Self {
213 pruning_threshold: Some(3 * 10_u64.pow(12)),
215 minimum_retention: Duration::from_secs(24 * 3600),
217 target_retention: Duration::from_secs(7 * 24 * 3600),
219 state_minimum_retention: Duration::from_secs(24 * 3600),
221 state_target_retention: Duration::from_secs(7 * 24 * 3600),
223 batch_size: 1000,
224 max_usage: 8000,
226 interval: Duration::from_secs(5400),
228 incremental_vacuum_pages: 8000,
230 state_tables: Vec::new(),
231 }
232 }
233}