diff --git a/book/cli/reth/node.md b/book/cli/reth/node.md index 6430d7a9247..b27c31f24e5 100644 --- a/book/cli/reth/node.md +++ b/book/cli/reth/node.md @@ -697,6 +697,9 @@ Pruning: --prune.receipts.before Prune receipts before the specified block number. The specified block number is not pruned + --prune.receiptslogfilter + Configure receipts log filter. Format: <`address`>:<`prune_mode`>[,<`address`>:<`prune_mode`>...] Where <`prune_mode`> can be 'full', 'distance:<`blocks`>', or 'before:<`block_number`>' + --prune.accounthistory.full Prunes all account history @@ -715,9 +718,6 @@ Pruning: --prune.storagehistory.before Prune storage history before the specified block number. The specified block number is not pruned - --prune.receiptslogfilter - Configure receipts log filter. Format: <`address`>:<`prune_mode`>[,<`address`>:<`prune_mode`>...] Where <`prune_mode`> can be 'full', 'distance:<`blocks`>', or 'before:<`block_number`>' - Engine: --engine.persistence-threshold Configure persistence threshold for engine experimental diff --git a/crates/node/builder/src/launch/common.rs b/crates/node/builder/src/launch/common.rs index 1e0bb0554e9..342f1047274 100644 --- a/crates/node/builder/src/launch/common.rs +++ b/crates/node/builder/src/launch/common.rs @@ -332,6 +332,7 @@ impl LaunchContextWith Option { let Some(mut node_prune_config) = self.node_config().prune_config() else { @@ -1086,7 +1087,7 @@ mod tests { storage_history_full: false, storage_history_distance: None, storage_history_before: None, - receipts_log_filter: vec![], + receipts_log_filter: None, }, ..NodeConfig::test() }; diff --git a/crates/node/core/src/args/pruning.rs b/crates/node/core/src/args/pruning.rs index cd852b9e168..9c7d3a9f5ad 100644 --- a/crates/node/core/src/args/pruning.rs +++ b/crates/node/core/src/args/pruning.rs @@ -3,7 +3,6 @@ use crate::args::error::ReceiptsLogError; use alloy_primitives::{Address, BlockNumber}; use clap::{builder::RangedU64ValueParser, Args}; -use reth_chainspec::EthChainSpec; use reth_config::config::PruneConfig; use reth_prune_types::{PruneMode, PruneModes, ReceiptsLogPruneConfig, MINIMUM_PRUNING_DISTANCE}; use std::collections::BTreeMap; @@ -56,6 +55,12 @@ pub struct PruningArgs { /// Prune receipts before the specified block number. The specified block number is not pruned. #[arg(long = "prune.receipts.before", value_name = "BLOCK_NUMBER", conflicts_with_all = &["receipts_full", "receipts_distance"])] pub receipts_before: Option, + // Receipts Log Filter + /// Configure receipts log filter. Format: + /// <`address`>:<`prune_mode`>[,<`address`>:<`prune_mode`>...] Where <`prune_mode`> can be + /// 'full', 'distance:<`blocks`>', or 'before:<`block_number`>' + #[arg(long = "prune.receiptslogfilter", value_name = "FILTER_CONFIG", conflicts_with_all = &["receipts_full", "receipts_distance", "receipts_before"], value_parser = parse_receipts_log_filter)] + pub receipts_log_filter: Option, // Account History /// Prunes all account history. @@ -81,18 +86,11 @@ pub struct PruningArgs { /// pruned. #[arg(long = "prune.storagehistory.before", value_name = "BLOCK_NUMBER", conflicts_with_all = &["storage_history_full", "storage_history_distance"])] pub storage_history_before: Option, - - // Receipts Log Filter - /// Configure receipts log filter. Format: - /// <`address`>:<`prune_mode`>[,<`address`>:<`prune_mode`>...] Where <`prune_mode`> can be - /// 'full', 'distance:<`blocks`>', or 'before:<`block_number`>' - #[arg(long = "prune.receiptslogfilter", value_name = "FILTER_CONFIG", value_delimiter = ',', value_parser = parse_receipts_log_filter)] - pub receipts_log_filter: Vec, } impl PruningArgs { /// Returns pruning configuration. - pub fn prune_config(&self, chain_spec: &impl EthChainSpec) -> Option { + pub fn prune_config(&self) -> Option { // Initialise with a default prune configuration. let mut config = PruneConfig::default(); @@ -103,21 +101,10 @@ impl PruningArgs { segments: PruneModes { sender_recovery: Some(PruneMode::Full), transaction_lookup: None, - // prune all receipts if chain doesn't have deposit contract specified in chain - // spec - receipts: chain_spec - .deposit_contract() - .map(|contract| PruneMode::Before(contract.block)) - .or(Some(PruneMode::Distance(MINIMUM_PRUNING_DISTANCE))), + receipts: Some(PruneMode::Distance(MINIMUM_PRUNING_DISTANCE)), account_history: Some(PruneMode::Distance(MINIMUM_PRUNING_DISTANCE)), storage_history: Some(PruneMode::Distance(MINIMUM_PRUNING_DISTANCE)), - receipts_log_filter: ReceiptsLogPruneConfig( - chain_spec - .deposit_contract() - .map(|contract| (contract.address, PruneMode::Before(contract.block))) - .into_iter() - .collect(), - ), + receipts_log_filter: Default::default(), }, } } @@ -141,9 +128,18 @@ impl PruningArgs { if let Some(mode) = self.storage_history_prune_mode() { config.segments.storage_history = Some(mode); } + if let Some(receipt_logs) = + self.receipts_log_filter.as_ref().filter(|c| !c.is_empty()).cloned() + { + config.segments.receipts_log_filter = receipt_logs; + // need to remove the receipts segment filter entirely because that takes precendence + // over the logs filter + config.segments.receipts.take(); + } Some(config) } + const fn sender_recovery_prune_mode(&self) -> Option { if self.sender_recovery_full { Some(PruneMode::Full) @@ -205,6 +201,7 @@ impl PruningArgs { } } +/// Parses `,` separated pruning info into [`ReceiptsLogPruneConfig`]. pub(crate) fn parse_receipts_log_filter( value: &str, ) -> Result { @@ -236,9 +233,8 @@ pub(crate) fn parse_receipts_log_filter( if parts.len() < 3 { return Err(ReceiptsLogError::InvalidFilterFormat(filter.to_string())); } - let block_number = parts[2] - .parse::() - .map_err(ReceiptsLogError::InvalidBlockNumber)?; + let block_number = + parts[2].parse::().map_err(ReceiptsLogError::InvalidBlockNumber)?; PruneMode::Before(block_number) } _ => return Err(ReceiptsLogError::InvalidPruneMode(parts[1].to_string())), @@ -251,6 +247,7 @@ pub(crate) fn parse_receipts_log_filter( #[cfg(test)] mod tests { use super::*; + use alloy_primitives::address; use clap::Parser; /// A helper type to parse Args more easily @@ -262,6 +259,22 @@ mod tests { #[test] fn pruning_args_sanity_check() { + let args = CommandParser::::parse_from([ + "reth", + "--prune.receiptslogfilter", + "0x0000000000000000000000000000000000000003:before:5000000", + ]) + .args; + let mut config = ReceiptsLogPruneConfig::default(); + config.0.insert( + address!("0x0000000000000000000000000000000000000003"), + PruneMode::Before(5000000), + ); + assert_eq!(args.receipts_log_filter, Some(config)); + } + + #[test] + fn parse_receiptslogfilter() { let default_args = PruningArgs::default(); let args = CommandParser::::parse_from(["reth"]).args; assert_eq!(args, default_args); diff --git a/crates/node/core/src/node_config.rs b/crates/node/core/src/node_config.rs index 1c76de3fe20..a3bd7e1dc78 100644 --- a/crates/node/core/src/node_config.rs +++ b/crates/node/core/src/node_config.rs @@ -283,11 +283,8 @@ impl NodeConfig { } /// Returns pruning configuration. - pub fn prune_config(&self) -> Option - where - ChainSpec: EthChainSpec, - { - self.pruning.prune_config(&self.chain) + pub fn prune_config(&self) -> Option { + self.pruning.prune_config() } /// Returns the max block that the node should run to, looking it up from the network if