@@ -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 ( ( ) )
@@ -1662,9 +1683,11 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
16621683 } ,
16631684 ( 5 , AwaitingInvoice ) => {
16641685 ( 0 , timer_ticks_without_response, required) ,
1686+ ( 2 , retry_strategy, required) ,
16651687 } ,
16661688 ( 7 , InvoiceReceived ) => {
16671689 ( 0 , payment_hash, required) ,
1690+ ( 2 , retry_strategy, required) ,
16681691 } ,
16691692) ;
16701693
@@ -1895,7 +1918,7 @@ mod tests {
18951918 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
18961919
18971920 assert ! ( !outbound_payments. has_pending_payments( ) ) ;
1898- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
1921+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
18991922 assert ! ( outbound_payments. has_pending_payments( ) ) ;
19001923
19011924 for _ in 0 ..INVOICE_REQUEST_TIMEOUT_TICKS {
@@ -1915,10 +1938,10 @@ mod tests {
19151938 ) ;
19161939 assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
19171940
1918- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
1941+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
19191942 assert ! ( outbound_payments. has_pending_payments( ) ) ;
19201943
1921- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_err( ) ) ;
1944+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_err( ) ) ;
19221945 }
19231946
19241947 #[ cfg( feature = "std" ) ]
@@ -1934,7 +1957,7 @@ mod tests {
19341957 let outbound_payments = OutboundPayments :: new ( ) ;
19351958 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
19361959
1937- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
1960+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
19381961 assert ! ( outbound_payments. has_pending_payments( ) ) ;
19391962
19401963 let created_at = now ( ) - DEFAULT_RELATIVE_EXPIRY ;
@@ -1980,7 +2003,7 @@ mod tests {
19802003 let outbound_payments = OutboundPayments :: new ( ) ;
19812004 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
19822005
1983- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
2006+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
19842007 assert ! ( outbound_payments. has_pending_payments( ) ) ;
19852008
19862009 let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
@@ -2033,7 +2056,7 @@ mod tests {
20332056 let outbound_payments = OutboundPayments :: new ( ) ;
20342057 let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
20352058
2036- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
2059+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
20372060 assert ! ( outbound_payments. has_pending_payments( ) ) ;
20382061
20392062 let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
@@ -2135,7 +2158,7 @@ mod tests {
21352158 assert ! ( !outbound_payments. has_pending_payments( ) ) ;
21362159 assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
21372160
2138- assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id) . is_ok( ) ) ;
2161+ assert ! ( outbound_payments. add_new_awaiting_invoice( payment_id, Retry :: Attempts ( 0 ) ) . is_ok( ) ) ;
21392162 assert ! ( outbound_payments. has_pending_payments( ) ) ;
21402163
21412164 assert_eq ! (
0 commit comments