@@ -53,9 +53,11 @@ pub(crate) enum PendingOutboundPayment {
5353 } ,
5454 AwaitingInvoice {
5555 timer_ticks_without_response : u8 ,
56+ retry_strategy : Retry ,
5657 } ,
5758 InvoiceReceived {
5859 payment_hash : PaymentHash ,
60+ retry_strategy : Retry ,
5961 } ,
6062 Retryable {
6163 retry_strategy : Option < Retry > ,
@@ -156,7 +158,7 @@ impl PendingOutboundPayment {
156158 match self {
157159 PendingOutboundPayment :: Legacy { .. } => None ,
158160 PendingOutboundPayment :: AwaitingInvoice { .. } => None ,
159- PendingOutboundPayment :: InvoiceReceived { payment_hash } => Some ( * payment_hash) ,
161+ PendingOutboundPayment :: InvoiceReceived { payment_hash, .. } => Some ( * payment_hash) ,
160162 PendingOutboundPayment :: Retryable { payment_hash, .. } => Some ( * payment_hash) ,
161163 PendingOutboundPayment :: Fulfilled { payment_hash, .. } => * payment_hash,
162164 PendingOutboundPayment :: Abandoned { payment_hash, .. } => Some ( * payment_hash) ,
@@ -186,7 +188,7 @@ impl PendingOutboundPayment {
186188 payment_hash : * payment_hash,
187189 reason : Some ( reason)
188190 } ;
189- } else if let PendingOutboundPayment :: InvoiceReceived { payment_hash } = self {
191+ } else if let PendingOutboundPayment :: InvoiceReceived { payment_hash, .. } = self {
190192 * self = PendingOutboundPayment :: Abandoned {
191193 session_privs : HashSet :: new ( ) ,
192194 payment_hash : * payment_hash,
@@ -272,6 +274,19 @@ pub enum Retry {
272274 Timeout ( core:: time:: Duration ) ,
273275}
274276
277+ #[ cfg( feature = "no-std" ) ]
278+ impl_writeable_tlv_based_enum ! ( Retry ,
279+ ;
280+ ( 0 , Attempts )
281+ ) ;
282+
283+ #[ cfg( not( feature = "no-std" ) ) ]
284+ impl_writeable_tlv_based_enum ! ( Retry ,
285+ ;
286+ ( 0 , Attempts ) ,
287+ ( 2 , Timeout )
288+ ) ;
289+
275290impl Retry {
276291 pub ( crate ) fn is_retryable_now ( & self , attempts : & PaymentAttempts ) -> bool {
277292 match ( self , attempts) {
@@ -587,8 +602,6 @@ pub(super) struct SendAlongPathArgs<'a> {
587602 pub session_priv_bytes : [ u8 ; 32 ] ,
588603}
589604
590- const BOLT_12_INVOICE_RETRY_STRATEGY : Retry = Retry :: Attempts ( 3 ) ;
591-
592605pub ( super ) struct OutboundPayments {
593606 pub ( super ) pending_outbound_payments : Mutex < HashMap < PaymentId , PendingOutboundPayment > > ,
594607 pub ( super ) retry_lock : Mutex < ( ) > ,
@@ -707,10 +720,15 @@ impl OutboundPayments {
707720 {
708721 let payment_hash = invoice. payment_hash ( ) ;
709722 match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
710- hash_map:: Entry :: Occupied ( entry) if entry. get ( ) . is_awaiting_invoice ( ) => {
711- * entry. into_mut ( ) = PendingOutboundPayment :: InvoiceReceived { payment_hash } ;
723+ hash_map:: Entry :: Occupied ( entry) => match entry. get ( ) {
724+ PendingOutboundPayment :: AwaitingInvoice { retry_strategy, .. } => {
725+ * entry. into_mut ( ) = PendingOutboundPayment :: InvoiceReceived {
726+ payment_hash,
727+ retry_strategy : * retry_strategy,
728+ } ;
729+ } ,
730+ _ => return Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
712731 } ,
713- hash_map:: Entry :: Occupied ( _) => return Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
714732 hash_map:: Entry :: Vacant ( _) => return Err ( Bolt12PaymentError :: UnexpectedInvoice ) ,
715733 } ;
716734
@@ -957,14 +975,14 @@ impl OutboundPayments {
957975 log_error ! ( logger, "Payment not yet sent" ) ;
958976 return
959977 } ,
960- PendingOutboundPayment :: InvoiceReceived { payment_hash } => {
978+ PendingOutboundPayment :: InvoiceReceived { payment_hash, retry_strategy } => {
961979 let total_amount = route_params. final_value_msat ;
962980 let recipient_onion = RecipientOnionFields {
963981 payment_secret : None ,
964982 payment_metadata : None ,
965983 custom_tlvs : vec ! [ ] ,
966984 } ;
967- let retry_strategy = Some ( BOLT_12_INVOICE_RETRY_STRATEGY ) ;
985+ let retry_strategy = Some ( * retry_strategy ) ;
968986 let payment_params = Some ( route_params. payment_params . clone ( ) ) ;
969987 let ( retryable_payment, onion_session_privs) = self . create_pending_payment (
970988 * payment_hash, recipient_onion. clone ( ) , None , & route,
@@ -1186,13 +1204,16 @@ impl OutboundPayments {
11861204 }
11871205
11881206 #[ allow( unused) ]
1189- pub ( super ) fn add_new_awaiting_invoice ( & self , payment_id : PaymentId ) -> Result < ( ) , ( ) > {
1207+ pub ( super ) fn add_new_awaiting_invoice (
1208+ & self , payment_id : PaymentId , retry_strategy : Retry
1209+ ) -> Result < ( ) , ( ) > {
11901210 let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
11911211 match pending_outbounds. entry ( payment_id) {
11921212 hash_map:: Entry :: Occupied ( _) => Err ( ( ) ) ,
11931213 hash_map:: Entry :: Vacant ( entry) => {
11941214 entry. insert ( PendingOutboundPayment :: AwaitingInvoice {
11951215 timer_ticks_without_response : 0 ,
1216+ retry_strategy,
11961217 } ) ;
11971218
11981219 Ok ( ( ) )
@@ -1667,9 +1688,11 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
16671688 } ,
16681689 ( 5 , AwaitingInvoice ) => {
16691690 ( 0 , timer_ticks_without_response, required) ,
1691+ ( 2 , retry_strategy, required) ,
16701692 } ,
16711693 ( 7 , InvoiceReceived ) => {
16721694 ( 0 , payment_hash, required) ,
1695+ ( 2 , retry_strategy, required) ,
16731696 } ,
16741697) ;
16751698
@@ -1891,7 +1914,7 @@ mod tests {
18911914 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
18921915
18931916 assert ! ( !outbound_payments. has_pending_payments( ) ) ;
1894- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
1917+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
18951918 assert ! ( outbound_payments. has_pending_payments( ) ) ;
18961919
18971920 for _ in 0 ..INVOICE_REQUEST_TIMEOUT_TICKS {
@@ -1909,10 +1932,10 @@ mod tests {
19091932 ) ;
19101933 assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
19111934
1912- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
1935+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
19131936 assert ! ( outbound_payments. has_pending_payments( ) ) ;
19141937
1915- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_err( ) ) ;
1938+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_err( ) ) ;
19161939 }
19171940
19181941 #[ test]
@@ -1922,7 +1945,7 @@ mod tests {
19221945 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
19231946
19241947 assert ! ( !outbound_payments. has_pending_payments( ) ) ;
1925- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
1948+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
19261949 assert ! ( outbound_payments. has_pending_payments( ) ) ;
19271950
19281951 outbound_payments. abandon_payment (
@@ -1950,7 +1973,7 @@ mod tests {
19501973 let outbound_payments = OutboundPayments :: new ( ) ;
19511974 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
19521975
1953- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
1976+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
19541977 assert ! ( outbound_payments. has_pending_payments( ) ) ;
19551978
19561979 let created_at = now ( ) - DEFAULT_RELATIVE_EXPIRY ;
@@ -1996,7 +2019,7 @@ mod tests {
19962019 let outbound_payments = OutboundPayments :: new ( ) ;
19972020 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
19982021
1999- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
2022+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
20002023 assert ! ( outbound_payments. has_pending_payments( ) ) ;
20012024
20022025 let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
@@ -2049,7 +2072,7 @@ mod tests {
20492072 let outbound_payments = OutboundPayments :: new ( ) ;
20502073 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
20512074
2052- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
2075+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
20532076 assert ! ( outbound_payments. has_pending_payments( ) ) ;
20542077
20552078 let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
@@ -2149,7 +2172,7 @@ mod tests {
21492172 assert ! ( !outbound_payments. has_pending_payments( ) ) ;
21502173 assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
21512174
2152- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
2175+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
21532176 assert ! ( outbound_payments. has_pending_payments( ) ) ;
21542177
21552178 assert_eq ! (
0 commit comments