reth_prune_types/
target.rs1use crate::{PruneMode, ReceiptsLogPruneConfig};
2
3pub const MINIMUM_PRUNING_DISTANCE: u64 = 32 * 2 + 10_000;
9
10#[derive(Debug, Clone, Default, Eq, PartialEq)]
12#[cfg_attr(any(test, feature = "serde"), derive(serde::Serialize, serde::Deserialize))]
13#[cfg_attr(any(test, feature = "serde"), serde(default))]
14pub struct PruneModes {
15 #[cfg_attr(any(test, feature = "serde"), serde(skip_serializing_if = "Option::is_none"))]
17 pub sender_recovery: Option<PruneMode>,
18 #[cfg_attr(any(test, feature = "serde"), serde(skip_serializing_if = "Option::is_none"))]
20 pub transaction_lookup: Option<PruneMode>,
21 #[cfg_attr(
24 any(test, feature = "serde"),
25 serde(
26 skip_serializing_if = "Option::is_none",
27 deserialize_with = "deserialize_opt_prune_mode_with_min_blocks::<MINIMUM_PRUNING_DISTANCE, _>"
28 )
29 )]
30 pub receipts: Option<PruneMode>,
31 #[cfg_attr(
33 any(test, feature = "serde"),
34 serde(
35 skip_serializing_if = "Option::is_none",
36 deserialize_with = "deserialize_opt_prune_mode_with_min_blocks::<MINIMUM_PRUNING_DISTANCE, _>"
37 )
38 )]
39 pub account_history: Option<PruneMode>,
40 #[cfg_attr(
42 any(test, feature = "serde"),
43 serde(
44 skip_serializing_if = "Option::is_none",
45 deserialize_with = "deserialize_opt_prune_mode_with_min_blocks::<MINIMUM_PRUNING_DISTANCE, _>"
46 )
47 )]
48 pub storage_history: Option<PruneMode>,
49 pub receipts_log_filter: ReceiptsLogPruneConfig,
55}
56
57impl PruneModes {
58 pub fn none() -> Self {
60 Self::default()
61 }
62
63 pub fn all() -> Self {
65 Self {
66 sender_recovery: Some(PruneMode::Full),
67 transaction_lookup: Some(PruneMode::Full),
68 receipts: Some(PruneMode::Full),
69 account_history: Some(PruneMode::Full),
70 storage_history: Some(PruneMode::Full),
71 receipts_log_filter: Default::default(),
72 }
73 }
74
75 pub fn has_receipts_pruning(&self) -> bool {
77 self.receipts.is_some() || !self.receipts_log_filter.is_empty()
78 }
79
80 pub fn is_empty(&self) -> bool {
82 self == &Self::none()
83 }
84}
85
86#[cfg(any(test, feature = "serde"))]
95fn deserialize_opt_prune_mode_with_min_blocks<
96 'de,
97 const MIN_BLOCKS: u64,
98 D: serde::Deserializer<'de>,
99>(
100 deserializer: D,
101) -> Result<Option<PruneMode>, D::Error> {
102 use alloc::format;
103 use serde::Deserialize;
104 let prune_mode = Option::<PruneMode>::deserialize(deserializer)?;
105
106 match prune_mode {
107 Some(PruneMode::Full) if MIN_BLOCKS > 0 => {
108 Err(serde::de::Error::invalid_value(
109 serde::de::Unexpected::Str("full"),
110 &format!("prune mode that leaves at least {MIN_BLOCKS} blocks in the database")
112 .as_str(),
113 ))
114 }
115 Some(PruneMode::Distance(distance)) if distance < MIN_BLOCKS => {
116 Err(serde::de::Error::invalid_value(
117 serde::de::Unexpected::Unsigned(distance),
118 &format!("prune mode that leaves at least {MIN_BLOCKS} blocks in the database")
120 .as_str(),
121 ))
122 }
123 _ => Ok(prune_mode),
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130 use assert_matches::assert_matches;
131 use serde::Deserialize;
132
133 #[test]
134 fn test_deserialize_opt_prune_mode_with_min_blocks() {
135 #[derive(Debug, Deserialize, PartialEq, Eq)]
136 struct V(
137 #[serde(deserialize_with = "deserialize_opt_prune_mode_with_min_blocks::<10, _>")]
138 Option<PruneMode>,
139 );
140
141 assert!(serde_json::from_str::<V>(r#"{"distance": 10}"#).is_ok());
142 assert_matches!(
143 serde_json::from_str::<V>(r#"{"distance": 9}"#),
144 Err(err) if err.to_string() == "invalid value: integer `9`, expected prune mode that leaves at least 10 blocks in the database"
145 );
146
147 assert_matches!(
148 serde_json::from_str::<V>(r#""full""#),
149 Err(err) if err.to_string() == "invalid value: string \"full\", expected prune mode that leaves at least 10 blocks in the database"
150 );
151 }
152}