@@ -15,7 +15,7 @@ use bitcoin::secp256k1::{self, Secp256k1, SecretKey};
15
15
16
16
use crate :: chain:: keysinterface:: { EntropySource , KeysInterface , NodeSigner , Recipient } ;
17
17
use crate :: ln:: { PaymentHash , PaymentPreimage , PaymentSecret } ;
18
- use crate :: ln:: channelmanager:: { HTLCSource , IDEMPOTENCY_TIMEOUT_TICKS , PaymentId } ;
18
+ use crate :: ln:: channelmanager:: { HTLCSource , IDEMPOTENCY_TIMEOUT_TICKS , MIN_HTLC_RELAY_HOLDING_CELL_MILLIS , PaymentId } ;
19
19
use crate :: ln:: msgs:: DecodeError ;
20
20
use crate :: ln:: onion_utils:: HTLCFailReason ;
21
21
use crate :: routing:: router:: { PaymentParameters , Route , RouteHop , RouteParameters , RoutePath } ;
@@ -30,6 +30,7 @@ use core::cmp;
30
30
use core:: fmt:: { self , Display , Formatter } ;
31
31
use core:: ops:: Deref ;
32
32
use core:: sync:: atomic:: { AtomicUsize , Ordering } ;
33
+ use core:: time:: Duration ;
33
34
34
35
use crate :: prelude:: * ;
35
36
use crate :: sync:: Mutex ;
@@ -795,7 +796,8 @@ impl OutboundPayments {
795
796
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
796
797
let mut all_paths_failed = false ;
797
798
let mut full_failure_ev = None ;
798
- if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( * payment_id) {
799
+ let mut pending_retry_ev = None ;
800
+ let attempts_remaining = if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( * payment_id) {
799
801
if !payment. get_mut ( ) . remove ( & session_priv_bytes, Some ( & path) ) {
800
802
log_trace ! ( logger, "Received duplicative fail for HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
801
803
return
@@ -804,6 +806,7 @@ impl OutboundPayments {
804
806
log_trace ! ( logger, "Received failure of HTLC with payment_hash {} after payment completion" , log_bytes!( payment_hash. 0 ) ) ;
805
807
return
806
808
}
809
+ let is_retryable = payment. get ( ) . is_retryable ( ) ;
807
810
if payment. get ( ) . remaining_parts ( ) == 0 {
808
811
all_paths_failed = true ;
809
812
if payment. get ( ) . abandoned ( ) {
@@ -814,10 +817,11 @@ impl OutboundPayments {
814
817
payment. remove ( ) ;
815
818
}
816
819
}
820
+ is_retryable
817
821
} else {
818
822
log_trace ! ( logger, "Received duplicative fail for HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
819
823
return
820
- }
824
+ } ;
821
825
let mut retry = if let Some ( payment_params_data) = payment_params {
822
826
let path_last_hop = path. last ( ) . expect ( "Outbound payments must have had a valid path" ) ;
823
827
Some ( RouteParameters {
@@ -856,6 +860,15 @@ impl OutboundPayments {
856
860
if let Some ( scid) = short_channel_id {
857
861
retry. as_mut ( ) . map ( |r| r. payment_params . previously_failed_channels . push ( scid) ) ;
858
862
}
863
+ if payment_retryable && attempts_remaining {
864
+ if let Some ( retry_params) = & retry {
865
+ debug_assert ! ( full_failure_ev. is_none( ) ) ;
866
+ pending_retry_ev = Some ( events:: Event :: PendingHTLCsForwardable {
867
+ time_forwardable : Duration :: from_millis ( MIN_HTLC_RELAY_HOLDING_CELL_MILLIS ) ,
868
+ } ) ;
869
+ self . retryable_htlcs . lock ( ) . unwrap ( ) . push ( ( * payment_id, retry_params. clone ( ) ) ) ;
870
+ }
871
+ }
859
872
events:: Event :: PaymentPathFailed {
860
873
payment_id : Some ( * payment_id) ,
861
874
payment_hash : payment_hash. clone ( ) ,
@@ -875,6 +888,7 @@ impl OutboundPayments {
875
888
let mut pending_events = pending_events. lock ( ) . unwrap ( ) ;
876
889
pending_events. push ( path_failure) ;
877
890
if let Some ( ev) = full_failure_ev { pending_events. push ( ev) ; }
891
+ if let Some ( ev) = pending_retry_ev { pending_events. push ( ev) ; }
878
892
}
879
893
880
894
pub ( super ) fn abandon_payment ( & self , payment_id : PaymentId ) -> Option < events:: Event > {
0 commit comments