reth_prune_types/
pruner.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use crate::{PruneCheckpoint, PruneMode, PruneSegment};
use alloy_primitives::{BlockNumber, TxNumber};
use derive_more::Display;

/// Pruner run output.
#[derive(Debug)]
pub struct PrunerOutput {
    /// Pruning progress.
    pub progress: PruneProgress,
    /// Pruning output for each segment.
    pub segments: Vec<(PruneSegment, SegmentOutput)>,
}

impl From<PruneProgress> for PrunerOutput {
    fn from(progress: PruneProgress) -> Self {
        Self { progress, segments: Vec::new() }
    }
}

/// Represents information of a pruner run for a segment.
#[derive(Debug, Clone, PartialEq, Eq, Display)]
#[display("(table={segment}, pruned={pruned}, status={progress})")]
pub struct PrunedSegmentInfo {
    /// The pruned segment
    pub segment: PruneSegment,
    /// Number of pruned entries
    pub pruned: usize,
    /// Prune progress
    pub progress: PruneProgress,
}

/// Segment pruning output.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct SegmentOutput {
    /// Segment pruning progress.
    pub progress: PruneProgress,
    /// Number of entries pruned, i.e. deleted from the database.
    pub pruned: usize,
    /// Pruning checkpoint to save to database, if any.
    pub checkpoint: Option<SegmentOutputCheckpoint>,
}

impl SegmentOutput {
    /// Returns a [`SegmentOutput`] with `done = true`, `pruned = 0` and `checkpoint = None`.
    /// Use when no pruning is needed.
    pub const fn done() -> Self {
        Self { progress: PruneProgress::Finished, pruned: 0, checkpoint: None }
    }

    /// Returns a [`SegmentOutput`] with `done = false`, `pruned = 0` and `checkpoint = None`.
    /// Use when pruning is needed but cannot be done.
    pub const fn not_done(
        reason: PruneInterruptReason,
        checkpoint: Option<SegmentOutputCheckpoint>,
    ) -> Self {
        Self { progress: PruneProgress::HasMoreData(reason), pruned: 0, checkpoint }
    }
}

/// Segment pruning checkpoint.
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq)]
pub struct SegmentOutputCheckpoint {
    /// Highest pruned block number. If it's [None], the pruning for block `0` is not finished yet.
    pub block_number: Option<BlockNumber>,
    /// Highest pruned transaction number, if applicable.
    pub tx_number: Option<TxNumber>,
}

impl SegmentOutputCheckpoint {
    /// Converts [`PruneCheckpoint`] to [`SegmentOutputCheckpoint`].
    pub const fn from_prune_checkpoint(checkpoint: PruneCheckpoint) -> Self {
        Self { block_number: checkpoint.block_number, tx_number: checkpoint.tx_number }
    }

    /// Converts [`SegmentOutputCheckpoint`] to [`PruneCheckpoint`] with the provided [`PruneMode`]
    pub const fn as_prune_checkpoint(&self, prune_mode: PruneMode) -> PruneCheckpoint {
        PruneCheckpoint { block_number: self.block_number, tx_number: self.tx_number, prune_mode }
    }
}

/// Progress of pruning.
#[derive(Debug, PartialEq, Eq, Clone, Copy, Display)]
pub enum PruneProgress {
    /// There is more data to prune.
    #[display("HasMoreData({_0})")]
    HasMoreData(PruneInterruptReason),
    /// Pruning has been finished.
    #[display("Finished")]
    Finished,
}

/// Reason for interrupting a prune run.
#[derive(Debug, PartialEq, Eq, Clone, Copy, Display)]
pub enum PruneInterruptReason {
    /// Prune run timed out.
    Timeout,
    /// Limit on the number of deleted entries (rows in the database) per prune run was reached.
    DeletedEntriesLimitReached,
    /// Unknown reason for stopping prune run.
    Unknown,
}

impl PruneInterruptReason {
    /// Returns `true` if the reason is timeout.
    pub const fn is_timeout(&self) -> bool {
        matches!(self, Self::Timeout)
    }

    /// Returns `true` if the reason is reaching the limit on deleted entries.
    pub const fn is_entries_limit_reached(&self) -> bool {
        matches!(self, Self::DeletedEntriesLimitReached)
    }
}

impl PruneProgress {
    /// Returns `true` if prune run is finished.
    pub const fn is_finished(&self) -> bool {
        matches!(self, Self::Finished)
    }
}