mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-01-09 07:17:56 -05:00
refactor(prune): derive EnumIter instead of explicit array of segments (#19465)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -9848,6 +9848,7 @@ dependencies = [
|
||||
"reth-codecs",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"strum 0.27.2",
|
||||
"thiserror 2.0.17",
|
||||
"toml",
|
||||
]
|
||||
|
||||
@@ -16,6 +16,7 @@ reth-codecs = { workspace = true, optional = true }
|
||||
|
||||
alloy-primitives.workspace = true
|
||||
derive_more.workspace = true
|
||||
strum = { workspace = true, features = ["derive"] }
|
||||
thiserror.workspace = true
|
||||
|
||||
modular-bitfield = { workspace = true, optional = true }
|
||||
@@ -42,6 +43,7 @@ std = [
|
||||
"serde?/std",
|
||||
"serde_json/std",
|
||||
"thiserror/std",
|
||||
"strum/std",
|
||||
]
|
||||
test-utils = [
|
||||
"std",
|
||||
|
||||
@@ -25,5 +25,5 @@ pub use pruner::{
|
||||
PruneInterruptReason, PruneProgress, PrunedSegmentInfo, PrunerOutput, SegmentOutput,
|
||||
SegmentOutputCheckpoint,
|
||||
};
|
||||
pub use segment::{PrunePurpose, PruneSegment, PruneSegmentError, PRUNE_SEGMENTS};
|
||||
pub use segment::{PrunePurpose, PruneSegment, PruneSegmentError};
|
||||
pub use target::{PruneModes, UnwindTargetPrunedError, MINIMUM_PRUNING_DISTANCE};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
use crate::MINIMUM_PRUNING_DISTANCE;
|
||||
use derive_more::Display;
|
||||
use strum::{EnumIter, IntoEnumIterator};
|
||||
use thiserror::Error;
|
||||
|
||||
/// Segment of the data that can be pruned.
|
||||
@@ -9,7 +10,7 @@ use thiserror::Error;
|
||||
/// VERY IMPORTANT NOTE: new variants must be added to the end of this enum, and old variants which
|
||||
/// are no longer used must not be removed from this enum. The variant index is encoded directly
|
||||
/// when writing to the `PruneCheckpoint` table, so changing the order here will corrupt the table.
|
||||
#[derive(Debug, Display, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
#[derive(Debug, Display, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, EnumIter)]
|
||||
#[cfg_attr(test, derive(arbitrary::Arbitrary))]
|
||||
#[cfg_attr(any(test, feature = "reth-codec"), derive(reth_codecs::Compact))]
|
||||
#[cfg_attr(any(test, feature = "reth-codec"), reth_codecs::add_arbitrary_tests(compact))]
|
||||
@@ -28,9 +29,11 @@ pub enum PruneSegment {
|
||||
/// Prune segment responsible for the `StorageChangeSets` and `StoragesHistory` tables.
|
||||
StorageHistory,
|
||||
#[deprecated = "Variant indexes cannot be changed"]
|
||||
#[strum(disabled)]
|
||||
/// Prune segment responsible for the `CanonicalHeaders`, `Headers` tables.
|
||||
Headers,
|
||||
#[deprecated = "Variant indexes cannot be changed"]
|
||||
#[strum(disabled)]
|
||||
/// Prune segment responsible for the `Transactions` table.
|
||||
Transactions,
|
||||
/// Prune segment responsible for all rows in `AccountsTrieChangeSets` and
|
||||
@@ -40,18 +43,6 @@ pub enum PruneSegment {
|
||||
Bodies,
|
||||
}
|
||||
|
||||
/// Array of [`PruneSegment`]s actively in use.
|
||||
pub const PRUNE_SEGMENTS: [PruneSegment; 8] = [
|
||||
PruneSegment::SenderRecovery,
|
||||
PruneSegment::TransactionLookup,
|
||||
PruneSegment::Receipts,
|
||||
PruneSegment::ContractLogs,
|
||||
PruneSegment::AccountHistory,
|
||||
PruneSegment::StorageHistory,
|
||||
PruneSegment::MerkleChangeSets,
|
||||
PruneSegment::Bodies,
|
||||
];
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(clippy::derivable_impls)]
|
||||
impl Default for PruneSegment {
|
||||
@@ -61,6 +52,14 @@ impl Default for PruneSegment {
|
||||
}
|
||||
|
||||
impl PruneSegment {
|
||||
/// Returns an iterator over all variants of [`PruneSegment`].
|
||||
///
|
||||
/// Excludes deprecated variants that are no longer used, but can still be found in the
|
||||
/// database.
|
||||
pub fn variants() -> impl Iterator<Item = Self> {
|
||||
Self::iter()
|
||||
}
|
||||
|
||||
/// Returns minimum number of blocks to keep in the database for this segment.
|
||||
pub const fn min_blocks(&self, purpose: PrunePurpose) -> u64 {
|
||||
match self {
|
||||
@@ -117,3 +116,20 @@ pub enum PruneSegmentError {
|
||||
#[error("the configuration provided for {0} is invalid")]
|
||||
Configuration(PruneSegment),
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_prune_segment_iter_excludes_deprecated() {
|
||||
let segments: Vec<PruneSegment> = PruneSegment::variants().collect();
|
||||
|
||||
// Verify deprecated variants are not included derived iter
|
||||
#[expect(deprecated)]
|
||||
{
|
||||
assert!(!segments.contains(&PruneSegment::Headers));
|
||||
assert!(!segments.contains(&PruneSegment::Transactions));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ use reth_primitives_traits::{
|
||||
Account, Block as _, BlockBody as _, Bytecode, RecoveredBlock, SealedHeader, StorageEntry,
|
||||
};
|
||||
use reth_prune_types::{
|
||||
PruneCheckpoint, PruneMode, PruneModes, PruneSegment, MINIMUM_PRUNING_DISTANCE, PRUNE_SEGMENTS,
|
||||
PruneCheckpoint, PruneMode, PruneModes, PruneSegment, MINIMUM_PRUNING_DISTANCE,
|
||||
};
|
||||
use reth_stages_types::{StageCheckpoint, StageId};
|
||||
use reth_static_file_types::StaticFileSegment;
|
||||
@@ -3024,13 +3024,12 @@ impl<TX: DbTx + 'static, N: NodeTypes> PruneCheckpointReader for DatabaseProvide
|
||||
}
|
||||
|
||||
fn get_prune_checkpoints(&self) -> ProviderResult<Vec<(PruneSegment, PruneCheckpoint)>> {
|
||||
Ok(PRUNE_SEGMENTS
|
||||
.iter()
|
||||
Ok(PruneSegment::variants()
|
||||
.filter_map(|segment| {
|
||||
self.tx
|
||||
.get::<tables::PruneCheckpoints>(*segment)
|
||||
.get::<tables::PruneCheckpoints>(segment)
|
||||
.transpose()
|
||||
.map(|chk| chk.map(|chk| (*segment, chk)))
|
||||
.map(|chk| chk.map(|chk| (segment, chk)))
|
||||
})
|
||||
.collect::<Result<_, _>>()?)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user