reth_prune_types/
segment.rs

1use crate::MINIMUM_PRUNING_DISTANCE;
2use derive_more::Display;
3use reth_codecs::{add_arbitrary_tests, Compact};
4use serde::{Deserialize, Serialize};
5use thiserror::Error;
6
7/// Segment of the data that can be pruned.
8#[derive(
9    Debug,
10    Display,
11    Clone,
12    Copy,
13    Eq,
14    PartialEq,
15    Ord,
16    PartialOrd,
17    Hash,
18    Serialize,
19    Deserialize,
20    Compact,
21)]
22#[cfg_attr(test, derive(arbitrary::Arbitrary))]
23#[add_arbitrary_tests(compact)]
24pub enum PruneSegment {
25    /// Prune segment responsible for the `TransactionSenders` table.
26    SenderRecovery,
27    /// Prune segment responsible for the `TransactionHashNumbers` table.
28    TransactionLookup,
29    /// Prune segment responsible for all rows in `Receipts` table.
30    Receipts,
31    /// Prune segment responsible for some rows in `Receipts` table filtered by logs.
32    ContractLogs,
33    /// Prune segment responsible for the `AccountChangeSets` and `AccountsHistory` tables.
34    AccountHistory,
35    /// Prune segment responsible for the `StorageChangeSets` and `StoragesHistory` tables.
36    StorageHistory,
37    /// Prune segment responsible for the `CanonicalHeaders`, `Headers` and
38    /// `HeaderTerminalDifficulties` tables.
39    Headers,
40    /// Prune segment responsible for the `Transactions` table.
41    Transactions,
42}
43
44impl PruneSegment {
45    /// Returns minimum number of blocks to left in the database for this segment.
46    pub const fn min_blocks(&self, purpose: PrunePurpose) -> u64 {
47        match self {
48            Self::SenderRecovery | Self::TransactionLookup | Self::Headers | Self::Transactions => {
49                0
50            }
51            Self::Receipts if purpose.is_static_file() => 0,
52            Self::ContractLogs | Self::AccountHistory | Self::StorageHistory => {
53                MINIMUM_PRUNING_DISTANCE
54            }
55            Self::Receipts => MINIMUM_PRUNING_DISTANCE,
56        }
57    }
58}
59
60/// Prune purpose.
61#[derive(Debug, Clone, Copy)]
62pub enum PrunePurpose {
63    /// Prune data according to user configuration.
64    User,
65    /// Prune data according to highest `static_files` to delete the data from database.
66    StaticFile,
67}
68
69impl PrunePurpose {
70    /// Returns true if the purpose is [`PrunePurpose::User`].
71    pub const fn is_user(self) -> bool {
72        matches!(self, Self::User)
73    }
74
75    /// Returns true if the purpose is [`PrunePurpose::StaticFile`].
76    pub const fn is_static_file(self) -> bool {
77        matches!(self, Self::StaticFile)
78    }
79}
80
81/// `PruneSegment` error type.
82#[derive(Debug, Error, PartialEq, Eq, Clone)]
83pub enum PruneSegmentError {
84    /// Invalid configuration of a prune segment.
85    #[error("the configuration provided for {0} is invalid")]
86    Configuration(PruneSegment),
87    /// Receipts have been pruned
88    #[error("receipts have been pruned")]
89    ReceiptsPruned,
90}
91
92#[cfg(test)]
93impl Default for PruneSegment {
94    fn default() -> Self {
95        Self::SenderRecovery
96    }
97}