@@ -336,7 +336,8 @@ impl ProofAggregator {
336336
337337 let max_retries = self . config . max_bump_retries ;
338338 let retry_interval = Duration :: from_secs ( self . config . bump_retry_interval_seconds ) ;
339- let fee_multiplier: f64 = self . config . bump_increase_fee_multiplier ;
339+ let base_bump_percentage = self . config . base_bump_percentage ; // e.g., 10
340+ let retry_attempt_percentage = self . config . retry_attempt_percentage ; // e.g., 5
340341
341342 for attempt in 0 ..max_retries {
342343 let mut tx_req = match aggregated_proof {
@@ -371,7 +372,12 @@ impl ProofAggregator {
371372 // Increase gas price/fees for retries before filling
372373 if attempt > 0 {
373374 tx_req = self
374- . update_gas_fees ( fee_multiplier, attempt as i32 , tx_req)
375+ . update_gas_fees (
376+ base_bump_percentage,
377+ retry_attempt_percentage,
378+ attempt as u64 ,
379+ tx_req,
380+ )
375381 . await ?;
376382 }
377383
@@ -469,39 +475,31 @@ impl ProofAggregator {
469475 ) )
470476 }
471477
472- // Updates the gas fees of a `TransactionRequest` for retry attempts by applying an exponential fee
473- // multiplier based on the retry number. This method is intended to be used when a previous transaction
474- // attempt was not confirmed (e.g. receipt timeout or transient failure). By increasing the gas fees
475- // on each retry, it improves the likelihood that the transaction will be included
476- // on the next block.
477- //
478- // Fee strategy:
479- // An exponential multiplier is computed on each iteration. For example, with `fee_multiplier = 1.2`:
480- // - `attempt = 1` → `1.2x`
481- // - `attempt = 2` → `1.44x`
482- // - `attempt = 3` → `1.728x`
478+ // Updates the gas fees of a `TransactionRequest` for retry attempts by applying a linear fee
479+ // bump based on the retry number. This method is intended to be used when a previous transaction
480+ // attempt was not confirmed (e.g. receipt timeout or transient failure).
483481 //
484- // If the transaction request doesn't have `max_fee_per_gas` set, the current network gas price is fetched
485- // from the provider, the max fee per gas is set to `current_gas_price * multiplier` and the max priority
486- // fee per gas is set to `current_gas_price * multiplier * 0.1`.
482+ // Fee strategy (similar to Go implementation):
483+ // The bump is calculated as: base_bump_percentage + (retry_count * retry_attempt_percentage)
484+ // For example, with `base_bump_percentage = 10` and `retry_attempt_percentage = 5`:
485+ // - `attempt = 1` → 10% + (1 * 5%) = 15% bump
486+ // - `attempt = 2` → 10% + (2 * 5%) = 20% bump
487+ // - `attempt = 3` → 10% + (3 * 5%) = 25% bump
487488 //
488- // If the transaction request already contains the fee fields, the existing max fee per gas is multiplied
489- // by `multiplier`, and the existing max priority fee per gas is multiplied by multiplier * 0.1`.
489+ // The bumped price is: current_gas_price * (1 + total_bump_percentage / 100)
490490 async fn update_gas_fees (
491491 & self ,
492- fee_multiplier : f64 ,
493- attempt : i32 ,
492+ base_bump_percentage : u64 ,
493+ retry_attempt_percentage : u64 ,
494+ attempt : u64 ,
494495 tx_req : alloy:: rpc:: types:: TransactionRequest ,
495496 ) -> Result < alloy:: rpc:: types:: TransactionRequest , RetryError < AggregatedProofSubmissionError > >
496497 {
497498 let provider = self . proof_aggregation_service . provider ( ) ;
498499
499- let multiplier = fee_multiplier. powi ( attempt) ;
500-
501- info ! (
502- "Retry attempt {} with increased fee ({}x)" ,
503- attempt, multiplier
504- ) ;
500+ // Calculate total bump percentage: base + (retry_count * retry_attempt)
501+ let incremental_retry_percentage = retry_attempt_percentage * attempt;
502+ let total_bump_percentage = base_bump_percentage + incremental_retry_percentage;
505503
506504 let mut current_tx_req = tx_req. clone ( ) ;
507505
@@ -510,26 +508,33 @@ impl ProofAggregator {
510508 RetryError :: Transient ( AggregatedProofSubmissionError :: GasPriceError ( e. to_string ( ) ) )
511509 } ) ?;
512510
513- let new_max_fee = ( current_gas_price as f64 * multiplier) as u128 ;
514- let new_priority_fee = ( current_gas_price as f64 * multiplier * 0.1 ) as u128 ;
511+ let new_max_fee =
512+ Self :: calculate_bumped_price ( current_gas_price, total_bump_percentage) ;
513+ let new_priority_fee = new_max_fee / 10 ; // 10% of max fee
515514
516515 current_tx_req = current_tx_req
517516 . with_max_fee_per_gas ( new_max_fee)
518517 . with_max_priority_fee_per_gas ( new_priority_fee) ;
519518 } else {
520519 if let Some ( max_fee) = current_tx_req. max_fee_per_gas {
521- let new_max_fee = ( max_fee as f64 * multiplier ) as u128 ;
520+ let new_max_fee = Self :: calculate_bumped_price ( max_fee, total_bump_percentage ) ;
522521 current_tx_req = current_tx_req. with_max_fee_per_gas ( new_max_fee) ;
523522 }
524523 if let Some ( priority_fee) = current_tx_req. max_priority_fee_per_gas {
525- let new_priority_fee = ( priority_fee as f64 * multiplier) as u128 ;
524+ let new_priority_fee =
525+ Self :: calculate_bumped_price ( priority_fee, total_bump_percentage) ;
526526 current_tx_req = current_tx_req. with_max_priority_fee_per_gas ( new_priority_fee) ;
527527 }
528528 }
529529
530530 Ok ( current_tx_req)
531531 }
532532
533+ fn calculate_bumped_price ( current_price : u128 , total_bump_percentage : u64 ) -> u128 {
534+ let bump_amount = ( current_price * total_bump_percentage as u128 ) / 100 ;
535+ current_price + bump_amount
536+ }
537+
533538 async fn wait_until_can_submit_aggregated_proof (
534539 & self ,
535540 ) -> Result < ( ) , RetryError < AggregatedProofSubmissionError > > {
0 commit comments