reth_prune_types/
segment.rs

1#![allow(deprecated)] // necessary to all defining deprecated `PruneSegment` variants
2
3use crate::MINIMUM_PRUNING_DISTANCE;
4use derive_more::Display;
5use thiserror::Error;
6
7/// Segment of the data that can be pruned.
8///
9/// VERY IMPORTANT NOTE: new variants must be added to the end of this enum, and old variants which
10/// are no longer used must not be removed from this enum. The variant index is encoded directly
11/// when writing to the `PruneCheckpoint` table, so changing the order here will corrupt the table.
12#[derive(Debug, Display, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
13#[cfg_attr(test, derive(arbitrary::Arbitrary))]
14#[cfg_attr(any(test, feature = "reth-codec"), derive(reth_codecs::Compact))]
15#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(compact))]
16#[cfg_attr(any(test, feature = "serde"), derive(serde::Serialize, serde::Deserialize))]
17pub enum PruneSegment {
18    /// Prune segment responsible for the `TransactionSenders` table.
19    SenderRecovery,
20    /// Prune segment responsible for the `TransactionHashNumbers` table.
21    TransactionLookup,
22    /// Prune segment responsible for all rows in `Receipts` table.
23    Receipts,
24    /// Prune segment responsible for some rows in `Receipts` table filtered by logs.
25    ContractLogs,
26    /// Prune segment responsible for the `AccountChangeSets` and `AccountsHistory` tables.
27    AccountHistory,
28    /// Prune segment responsible for the `StorageChangeSets` and `StoragesHistory` tables.
29    StorageHistory,
30    #[deprecated = "Variant indexes cannot be changed"]
31    /// Prune segment responsible for the `CanonicalHeaders`, `Headers` tables.
32    Headers,
33    #[deprecated = "Variant indexes cannot be changed"]
34    /// Prune segment responsible for the `Transactions` table.
35    Transactions,
36    /// Prune segment responsible for all rows in `AccountsTrieChangeSets` and
37    /// `StoragesTrieChangeSets` table.
38    MerkleChangeSets,
39    /// Prune segment responsible for bodies (transactions in static files).
40    Bodies,
41}
42
43/// Array of [`PruneSegment`]s actively in use.
44pub const PRUNE_SEGMENTS: [PruneSegment; 8] = [
45    PruneSegment::SenderRecovery,
46    PruneSegment::TransactionLookup,
47    PruneSegment::Receipts,
48    PruneSegment::ContractLogs,
49    PruneSegment::AccountHistory,
50    PruneSegment::StorageHistory,
51    PruneSegment::MerkleChangeSets,
52    PruneSegment::Bodies,
53];
54
55#[cfg(test)]
56#[allow(clippy::derivable_impls)]
57impl Default for PruneSegment {
58    fn default() -> Self {
59        Self::SenderRecovery
60    }
61}
62
63impl PruneSegment {
64    /// Returns minimum number of blocks to keep in the database for this segment.
65    pub const fn min_blocks(&self, purpose: PrunePurpose) -> u64 {
66        match self {
67            Self::SenderRecovery | Self::TransactionLookup => 0,
68            Self::Receipts if purpose.is_static_file() => 0,
69            Self::ContractLogs |
70            Self::AccountHistory |
71            Self::StorageHistory |
72            Self::MerkleChangeSets |
73            Self::Bodies |
74            Self::Receipts => MINIMUM_PRUNING_DISTANCE,
75            #[expect(deprecated)]
76            #[expect(clippy::match_same_arms)]
77            Self::Headers | Self::Transactions => 0,
78        }
79    }
80
81    /// Returns true if this is [`Self::AccountHistory`].
82    pub const fn is_account_history(&self) -> bool {
83        matches!(self, Self::AccountHistory)
84    }
85
86    /// Returns true if this is [`Self::StorageHistory`].
87    pub const fn is_storage_history(&self) -> bool {
88        matches!(self, Self::StorageHistory)
89    }
90}
91
92/// Prune purpose.
93#[derive(Debug, Clone, Copy)]
94pub enum PrunePurpose {
95    /// Prune data according to user configuration.
96    User,
97    /// Prune data according to highest `static_files` to delete the data from database.
98    StaticFile,
99}
100
101impl PrunePurpose {
102    /// Returns true if the purpose is [`PrunePurpose::User`].
103    pub const fn is_user(self) -> bool {
104        matches!(self, Self::User)
105    }
106
107    /// Returns true if the purpose is [`PrunePurpose::StaticFile`].
108    pub const fn is_static_file(self) -> bool {
109        matches!(self, Self::StaticFile)
110    }
111}
112
113/// `PruneSegment` error type.
114#[derive(Debug, Error, PartialEq, Eq, Clone)]
115pub enum PruneSegmentError {
116    /// Invalid configuration of a prune segment.
117    #[error("the configuration provided for {0} is invalid")]
118    Configuration(PruneSegment),
119}