11//! Pruning and full node arguments
22
3- use crate :: { args:: error:: ReceiptsLogError , primitives:: EthereumHardfork } ;
4- use alloy_primitives:: { Address , BlockNumber } ;
3+ use std:: ops:: Not ;
4+
5+ use crate :: primitives:: EthereumHardfork ;
6+ use alloy_primitives:: BlockNumber ;
57use clap:: { builder:: RangedU64ValueParser , Args } ;
68use reth_chainspec:: EthereumHardforks ;
79use reth_config:: config:: PruneConfig ;
8- use reth_prune_types:: { PruneMode , PruneModes , ReceiptsLogPruneConfig , MINIMUM_PRUNING_DISTANCE } ;
9- use std:: { collections:: BTreeMap , ops:: Not } ;
10+ use reth_prune_types:: { PruneMode , PruneModes , MINIMUM_PRUNING_DISTANCE } ;
1011
1112/// Parameters for pruning and full node
1213#[ derive( Debug , Clone , Args , PartialEq , Eq , Default ) ]
@@ -59,12 +60,10 @@ pub struct PruningArgs {
5960 /// Prune receipts before the specified block number. The specified block number is not pruned.
6061 #[ arg( long = "prune.receipts.before" , value_name = "BLOCK_NUMBER" , conflicts_with_all = & [ "receipts_full" , "receipts_pre_merge" , "receipts_distance" ] ) ]
6162 pub receipts_before : Option < BlockNumber > ,
62- // Receipts Log Filter
63- /// Configure receipts log filter. Format:
64- /// <`address`>:<`prune_mode`>... where <`prune_mode`> can be 'full', 'distance:<`blocks`>', or
65- /// 'before:<`block_number`>'
66- #[ arg( long = "prune.receiptslogfilter" , value_name = "FILTER_CONFIG" , conflicts_with_all = & [ "receipts_full" , "receipts_pre_merge" , "receipts_distance" , "receipts_before" ] , value_parser = parse_receipts_log_filter) ]
67- pub receipts_log_filter : Option < ReceiptsLogPruneConfig > ,
63+ /// Receipts Log Filter
64+ #[ arg( long = "prune.receiptslogfilter" , value_name = "FILTER_CONFIG" , hide = true ) ]
65+ #[ deprecated]
66+ pub receipts_log_filter : Option < String > ,
6867
6968 // Account History
7069 /// Prunes all account history.
@@ -130,7 +129,8 @@ impl PruningArgs {
130129 // TODO: set default to pre-merge block if available
131130 bodies_history : None ,
132131 merkle_changesets : PruneMode :: Distance ( MINIMUM_PRUNING_DISTANCE ) ,
133- receipts_log_filter : Default :: default ( ) ,
132+ #[ expect( deprecated) ]
133+ receipts_log_filter : ( ) ,
134134 } ,
135135 }
136136 }
@@ -157,13 +157,14 @@ impl PruningArgs {
157157 if let Some ( mode) = self . storage_history_prune_mode ( ) {
158158 config. segments . storage_history = Some ( mode) ;
159159 }
160- if let Some ( receipt_logs) =
161- self . receipts_log_filter . as_ref ( ) . filter ( |c| !c. is_empty ( ) ) . cloned ( )
162- {
163- config. segments . receipts_log_filter = receipt_logs;
164- // need to remove the receipts segment filter entirely because that takes precedence
165- // over the logs filter
166- config. segments . receipts . take ( ) ;
160+
161+ // Log warning if receipts_log_filter is set (deprecated feature)
162+ #[ expect( deprecated) ]
163+ if self . receipts_log_filter . is_some ( ) {
164+ tracing:: warn!(
165+ target: "reth::cli" ,
166+ "The --prune.receiptslogfilter flag is deprecated and has no effect. It will be removed in a future release."
167+ ) ;
167168 }
168169
169170 config. is_default ( ) . not ( ) . then_some ( config)
@@ -251,141 +252,3 @@ impl PruningArgs {
251252 }
252253 }
253254}
254-
255- /// Parses `,` separated pruning info into [`ReceiptsLogPruneConfig`].
256- pub ( crate ) fn parse_receipts_log_filter (
257- value : & str ,
258- ) -> Result < ReceiptsLogPruneConfig , ReceiptsLogError > {
259- let mut config = BTreeMap :: new ( ) ;
260- // Split out each of the filters.
261- let filters = value. split ( ',' ) ;
262- for filter in filters {
263- let parts: Vec < & str > = filter. split ( ':' ) . collect ( ) ;
264- if parts. len ( ) < 2 {
265- return Err ( ReceiptsLogError :: InvalidFilterFormat ( filter. to_string ( ) ) ) ;
266- }
267- // Parse the address
268- let address = parts[ 0 ]
269- . parse :: < Address > ( )
270- . map_err ( |_| ReceiptsLogError :: InvalidAddress ( parts[ 0 ] . to_string ( ) ) ) ?;
271-
272- // Parse the prune mode
273- let prune_mode = match parts[ 1 ] {
274- "full" => PruneMode :: Full ,
275- s if s. starts_with ( "distance" ) => {
276- if parts. len ( ) < 3 {
277- return Err ( ReceiptsLogError :: InvalidFilterFormat ( filter. to_string ( ) ) ) ;
278- }
279- let distance =
280- parts[ 2 ] . parse :: < u64 > ( ) . map_err ( ReceiptsLogError :: InvalidDistance ) ?;
281- PruneMode :: Distance ( distance)
282- }
283- s if s. starts_with ( "before" ) => {
284- if parts. len ( ) < 3 {
285- return Err ( ReceiptsLogError :: InvalidFilterFormat ( filter. to_string ( ) ) ) ;
286- }
287- let block_number =
288- parts[ 2 ] . parse :: < u64 > ( ) . map_err ( ReceiptsLogError :: InvalidBlockNumber ) ?;
289- PruneMode :: Before ( block_number)
290- }
291- _ => return Err ( ReceiptsLogError :: InvalidPruneMode ( parts[ 1 ] . to_string ( ) ) ) ,
292- } ;
293- config. insert ( address, prune_mode) ;
294- }
295- Ok ( ReceiptsLogPruneConfig ( config) )
296- }
297-
298- #[ cfg( test) ]
299- mod tests {
300- use super :: * ;
301- use alloy_primitives:: address;
302- use clap:: Parser ;
303-
304- /// A helper type to parse Args more easily
305- #[ derive( Parser ) ]
306- struct CommandParser < T : Args > {
307- #[ command( flatten) ]
308- args : T ,
309- }
310-
311- #[ test]
312- fn pruning_args_sanity_check ( ) {
313- let args = CommandParser :: < PruningArgs > :: parse_from ( [
314- "reth" ,
315- "--prune.receiptslogfilter" ,
316- "0x0000000000000000000000000000000000000003:before:5000000" ,
317- ] )
318- . args ;
319- let mut config = ReceiptsLogPruneConfig :: default ( ) ;
320- config. 0 . insert (
321- address ! ( "0x0000000000000000000000000000000000000003" ) ,
322- PruneMode :: Before ( 5000000 ) ,
323- ) ;
324- assert_eq ! ( args. receipts_log_filter, Some ( config) ) ;
325- }
326-
327- #[ test]
328- fn parse_receiptslogfilter ( ) {
329- let default_args = PruningArgs :: default ( ) ;
330- let args = CommandParser :: < PruningArgs > :: parse_from ( [ "reth" ] ) . args ;
331- assert_eq ! ( args, default_args) ;
332- }
333-
334- #[ test]
335- fn test_parse_receipts_log_filter ( ) {
336- let filter1 = "0x0000000000000000000000000000000000000001:full" ;
337- let filter2 = "0x0000000000000000000000000000000000000002:distance:1000" ;
338- let filter3 = "0x0000000000000000000000000000000000000003:before:5000000" ;
339- let filters = [ filter1, filter2, filter3] . join ( "," ) ;
340-
341- // Args can be parsed.
342- let result = parse_receipts_log_filter ( & filters) ;
343- assert ! ( result. is_ok( ) ) ;
344- let config = result. unwrap ( ) ;
345- assert_eq ! ( config. 0 . len( ) , 3 ) ;
346-
347- // Check that the args were parsed correctly.
348- let addr1: Address = "0x0000000000000000000000000000000000000001" . parse ( ) . unwrap ( ) ;
349- let addr2: Address = "0x0000000000000000000000000000000000000002" . parse ( ) . unwrap ( ) ;
350- let addr3: Address = "0x0000000000000000000000000000000000000003" . parse ( ) . unwrap ( ) ;
351-
352- assert_eq ! ( config. 0 . get( & addr1) , Some ( & PruneMode :: Full ) ) ;
353- assert_eq ! ( config. 0 . get( & addr2) , Some ( & PruneMode :: Distance ( 1000 ) ) ) ;
354- assert_eq ! ( config. 0 . get( & addr3) , Some ( & PruneMode :: Before ( 5000000 ) ) ) ;
355- }
356-
357- #[ test]
358- fn test_parse_receipts_log_filter_invalid_filter_format ( ) {
359- let result = parse_receipts_log_filter ( "invalid_format" ) ;
360- assert ! ( matches!( result, Err ( ReceiptsLogError :: InvalidFilterFormat ( _) ) ) ) ;
361- }
362-
363- #[ test]
364- fn test_parse_receipts_log_filter_invalid_address ( ) {
365- let result = parse_receipts_log_filter ( "invalid_address:full" ) ;
366- assert ! ( matches!( result, Err ( ReceiptsLogError :: InvalidAddress ( _) ) ) ) ;
367- }
368-
369- #[ test]
370- fn test_parse_receipts_log_filter_invalid_prune_mode ( ) {
371- let result =
372- parse_receipts_log_filter ( "0x0000000000000000000000000000000000000000:invalid_mode" ) ;
373- assert ! ( matches!( result, Err ( ReceiptsLogError :: InvalidPruneMode ( _) ) ) ) ;
374- }
375-
376- #[ test]
377- fn test_parse_receipts_log_filter_invalid_distance ( ) {
378- let result = parse_receipts_log_filter (
379- "0x0000000000000000000000000000000000000000:distance:invalid_distance" ,
380- ) ;
381- assert ! ( matches!( result, Err ( ReceiptsLogError :: InvalidDistance ( _) ) ) ) ;
382- }
383-
384- #[ test]
385- fn test_parse_receipts_log_filter_invalid_block_number ( ) {
386- let result = parse_receipts_log_filter (
387- "0x0000000000000000000000000000000000000000:before:invalid_block" ,
388- ) ;
389- assert ! ( matches!( result, Err ( ReceiptsLogError :: InvalidBlockNumber ( _) ) ) ) ;
390- }
391- }
0 commit comments