mirror of
https://github.com/paradigmxyz/reth.git
synced 2026-02-11 23:45:05 -05:00
feat(bin, prune): pass prune segments from CLI & refactor modes (#4964)
This commit is contained in:
@@ -53,7 +53,7 @@ impl ReceiptsLogPruneConfig {
|
||||
// Reminder, that we increment because the [`BlockNumber`] key of the new map should be
|
||||
// viewed as `PruneMode::Before(block)`
|
||||
let block = (pruned_block + 1).max(
|
||||
mode.prune_target_block(tip, MINIMUM_PRUNING_DISTANCE, PruneSegment::ContractLogs)?
|
||||
mode.prune_target_block(tip, PruneSegment::ContractLogs)?
|
||||
.map(|(block, _)| block)
|
||||
.unwrap_or_default() +
|
||||
1,
|
||||
@@ -75,11 +75,9 @@ impl ReceiptsLogPruneConfig {
|
||||
|
||||
for (_, mode) in self.0.iter() {
|
||||
if let PruneMode::Distance(_) = mode {
|
||||
if let Some((block, _)) = mode.prune_target_block(
|
||||
tip,
|
||||
MINIMUM_PRUNING_DISTANCE,
|
||||
PruneSegment::ContractLogs,
|
||||
)? {
|
||||
if let Some((block, _)) =
|
||||
mode.prune_target_block(tip, PruneSegment::ContractLogs)?
|
||||
{
|
||||
lowest = Some(lowest.unwrap_or(u64::MAX).min(block));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,17 +20,16 @@ impl PruneMode {
|
||||
pub fn prune_target_block(
|
||||
&self,
|
||||
tip: BlockNumber,
|
||||
min_blocks: u64,
|
||||
segment: PruneSegment,
|
||||
) -> Result<Option<(BlockNumber, PruneMode)>, PruneSegmentError> {
|
||||
let result = match self {
|
||||
PruneMode::Full if min_blocks == 0 => Some((tip, *self)),
|
||||
PruneMode::Full if segment.min_blocks() == 0 => Some((tip, *self)),
|
||||
PruneMode::Distance(distance) if *distance > tip => None, // Nothing to prune yet
|
||||
PruneMode::Distance(distance) if *distance >= min_blocks => {
|
||||
PruneMode::Distance(distance) if *distance >= segment.min_blocks() => {
|
||||
Some((tip - distance, *self))
|
||||
}
|
||||
PruneMode::Before(n) if *n > tip => None, // Nothing to prune yet
|
||||
PruneMode::Before(n) if tip - n >= min_blocks => Some((n - 1, *self)),
|
||||
PruneMode::Before(n) if tip - n >= segment.min_blocks() => Some((n - 1, *self)),
|
||||
_ => return Err(PruneSegmentError::Configuration(segment)),
|
||||
};
|
||||
Ok(result)
|
||||
@@ -72,7 +71,6 @@ mod tests {
|
||||
#[test]
|
||||
fn test_prune_target_block() {
|
||||
let tip = 20000;
|
||||
let min_blocks = MINIMUM_PRUNING_DISTANCE;
|
||||
let segment = PruneSegment::Receipts;
|
||||
|
||||
let tests = vec![
|
||||
@@ -80,7 +78,10 @@ mod tests {
|
||||
(PruneMode::Full, Err(PruneSegmentError::Configuration(segment))),
|
||||
// Nothing to prune
|
||||
(PruneMode::Distance(tip + 1), Ok(None)),
|
||||
(PruneMode::Distance(min_blocks + 1), Ok(Some(tip - (min_blocks + 1)))),
|
||||
(
|
||||
PruneMode::Distance(segment.min_blocks() + 1),
|
||||
Ok(Some(tip - (segment.min_blocks() + 1))),
|
||||
),
|
||||
// Nothing to prune
|
||||
(PruneMode::Before(tip + 1), Ok(None)),
|
||||
(
|
||||
@@ -96,7 +97,7 @@ mod tests {
|
||||
|
||||
for (index, (mode, expected_result)) in tests.into_iter().enumerate() {
|
||||
assert_eq!(
|
||||
mode.prune_target_block(tip, min_blocks, segment),
|
||||
mode.prune_target_block(tip, segment),
|
||||
expected_result.map(|r| r.map(|b| (b, mode))),
|
||||
"Test {} failed",
|
||||
index + 1,
|
||||
@@ -105,7 +106,7 @@ mod tests {
|
||||
|
||||
// Test for a scenario where there are no minimum blocks and Full can be used
|
||||
assert_eq!(
|
||||
PruneMode::Full.prune_target_block(tip, 0, segment),
|
||||
PruneMode::Full.prune_target_block(tip, PruneSegment::Transactions),
|
||||
Ok(Some((tip, PruneMode::Full))),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::MINIMUM_PRUNING_DISTANCE;
|
||||
use derive_more::Display;
|
||||
use reth_codecs::{main_codec, Compact};
|
||||
use thiserror::Error;
|
||||
@@ -24,6 +25,20 @@ pub enum PruneSegment {
|
||||
Transactions,
|
||||
}
|
||||
|
||||
impl PruneSegment {
|
||||
/// Returns minimum number of blocks to left in the database for this segment.
|
||||
pub fn min_blocks(&self) -> u64 {
|
||||
match self {
|
||||
Self::SenderRecovery | Self::TransactionLookup | Self::Headers | Self::Transactions => {
|
||||
0
|
||||
}
|
||||
Self::Receipts | Self::ContractLogs | Self::AccountHistory | Self::StorageHistory => {
|
||||
MINIMUM_PRUNING_DISTANCE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// PruneSegment error type.
|
||||
#[derive(Debug, Error, PartialEq, Eq, Clone)]
|
||||
pub enum PruneSegmentError {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use crate::{
|
||||
prune::PruneSegmentError, serde_helper::deserialize_opt_prune_mode_with_min_blocks,
|
||||
BlockNumber, PruneMode, PruneSegment, ReceiptsLogPruneConfig,
|
||||
serde_helper::deserialize_opt_prune_mode_with_min_blocks, PruneMode, ReceiptsLogPruneConfig,
|
||||
};
|
||||
use paste::paste;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Minimum distance from the tip necessary for the node to work correctly:
|
||||
@@ -44,69 +42,26 @@ pub struct PruneModes {
|
||||
/// Receipts pruning configuration by retaining only those receipts that contain logs emitted
|
||||
/// by the specified addresses, discarding others. This setting is overridden by `receipts`.
|
||||
///
|
||||
/// The [`BlockNumber`] represents the starting block from which point onwards the receipts are
|
||||
/// preserved.
|
||||
/// The [BlockNumber](`crate::BlockNumber`) represents the starting block from which point
|
||||
/// onwards the receipts are preserved.
|
||||
pub receipts_log_filter: ReceiptsLogPruneConfig,
|
||||
}
|
||||
|
||||
macro_rules! impl_prune_segments {
|
||||
($(($segment:ident, $variant:ident, $min_blocks:expr)),+) => {
|
||||
$(
|
||||
paste! {
|
||||
#[doc = concat!(
|
||||
"Check if ",
|
||||
stringify!($variant),
|
||||
" should be pruned at the target block according to the provided tip."
|
||||
)]
|
||||
pub fn [<should_prune_ $segment>](&self, block: BlockNumber, tip: BlockNumber) -> bool {
|
||||
if let Some(mode) = &self.$segment {
|
||||
return mode.should_prune(block, tip)
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
)+
|
||||
|
||||
$(
|
||||
paste! {
|
||||
#[doc = concat!(
|
||||
"Returns block up to which ",
|
||||
stringify!($variant),
|
||||
" pruning needs to be done, inclusive, according to the provided tip."
|
||||
)]
|
||||
pub fn [<prune_target_block_ $segment>](&self, tip: BlockNumber) -> Result<Option<(BlockNumber, PruneMode)>, PruneSegmentError> {
|
||||
match self.$segment {
|
||||
Some(mode) => mode.prune_target_block(tip, $min_blocks.unwrap_or_default(), PruneSegment::$variant),
|
||||
None => Ok(None)
|
||||
}
|
||||
}
|
||||
}
|
||||
)+
|
||||
|
||||
/// Sets pruning to all targets.
|
||||
pub fn all() -> Self {
|
||||
Self {
|
||||
$(
|
||||
$segment: Some(PruneMode::Full),
|
||||
)+
|
||||
receipts_log_filter: Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
impl PruneModes {
|
||||
/// Sets pruning to no target.
|
||||
pub fn none() -> Self {
|
||||
PruneModes::default()
|
||||
}
|
||||
|
||||
impl_prune_segments!(
|
||||
(sender_recovery, SenderRecovery, None),
|
||||
(transaction_lookup, TransactionLookup, None),
|
||||
(receipts, Receipts, Some(MINIMUM_PRUNING_DISTANCE)),
|
||||
(account_history, AccountHistory, Some(MINIMUM_PRUNING_DISTANCE)),
|
||||
(storage_history, StorageHistory, Some(MINIMUM_PRUNING_DISTANCE))
|
||||
);
|
||||
/// Sets pruning to all targets.
|
||||
pub fn all() -> Self {
|
||||
Self {
|
||||
sender_recovery: Some(PruneMode::Full),
|
||||
transaction_lookup: Some(PruneMode::Full),
|
||||
receipts: Some(PruneMode::Full),
|
||||
account_history: Some(PruneMode::Full),
|
||||
storage_history: Some(PruneMode::Full),
|
||||
receipts_log_filter: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user