@@ -53,9 +53,11 @@ pub(crate) enum PendingOutboundPayment {
53
53
} ,
54
54
AwaitingInvoice {
55
55
timer_ticks_without_response : u8 ,
56
+ retry_strategy : Retry ,
56
57
} ,
57
58
InvoiceReceived {
58
59
payment_hash : PaymentHash ,
60
+ retry_strategy : Retry ,
59
61
} ,
60
62
Retryable {
61
63
retry_strategy : Option < Retry > ,
@@ -156,7 +158,7 @@ impl PendingOutboundPayment {
156
158
match self {
157
159
PendingOutboundPayment :: Legacy { .. } => None ,
158
160
PendingOutboundPayment :: AwaitingInvoice { .. } => None ,
159
- PendingOutboundPayment :: InvoiceReceived { payment_hash } => Some ( * payment_hash) ,
161
+ PendingOutboundPayment :: InvoiceReceived { payment_hash, .. } => Some ( * payment_hash) ,
160
162
PendingOutboundPayment :: Retryable { payment_hash, .. } => Some ( * payment_hash) ,
161
163
PendingOutboundPayment :: Fulfilled { payment_hash, .. } => * payment_hash,
162
164
PendingOutboundPayment :: Abandoned { payment_hash, .. } => Some ( * payment_hash) ,
@@ -186,7 +188,7 @@ impl PendingOutboundPayment {
186
188
payment_hash : * payment_hash,
187
189
reason : Some ( reason)
188
190
} ;
189
- } else if let PendingOutboundPayment :: InvoiceReceived { payment_hash } = self {
191
+ } else if let PendingOutboundPayment :: InvoiceReceived { payment_hash, .. } = self {
190
192
* self = PendingOutboundPayment :: Abandoned {
191
193
session_privs : HashSet :: new ( ) ,
192
194
payment_hash : * payment_hash,
@@ -272,6 +274,19 @@ pub enum Retry {
272
274
Timeout ( core:: time:: Duration ) ,
273
275
}
274
276
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
+
275
290
impl Retry {
276
291
pub ( crate ) fn is_retryable_now ( & self , attempts : & PaymentAttempts ) -> bool {
277
292
match ( self , attempts) {
@@ -587,8 +602,6 @@ pub(super) struct SendAlongPathArgs<'a> {
587
602
pub session_priv_bytes : [ u8 ; 32 ] ,
588
603
}
589
604
590
- const BOLT_12_INVOICE_RETRY_STRATEGY : Retry = Retry :: Attempts ( 3 ) ;
591
-
592
605
pub ( super ) struct OutboundPayments {
593
606
pub ( super ) pending_outbound_payments : Mutex < HashMap < PaymentId , PendingOutboundPayment > > ,
594
607
pub ( super ) retry_lock : Mutex < ( ) > ,
@@ -707,10 +720,15 @@ impl OutboundPayments {
707
720
{
708
721
let payment_hash = invoice. payment_hash ( ) ;
709
722
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 ) ,
712
731
} ,
713
- hash_map:: Entry :: Occupied ( _) => return Err ( Bolt12PaymentError :: DuplicateInvoice ) ,
714
732
hash_map:: Entry :: Vacant ( _) => return Err ( Bolt12PaymentError :: UnexpectedInvoice ) ,
715
733
} ;
716
734
@@ -957,14 +975,14 @@ impl OutboundPayments {
957
975
log_error ! ( logger, "Payment not yet sent" ) ;
958
976
return
959
977
} ,
960
- PendingOutboundPayment :: InvoiceReceived { payment_hash } => {
978
+ PendingOutboundPayment :: InvoiceReceived { payment_hash, retry_strategy } => {
961
979
let total_amount = route_params. final_value_msat ;
962
980
let recipient_onion = RecipientOnionFields {
963
981
payment_secret : None ,
964
982
payment_metadata : None ,
965
983
custom_tlvs : vec ! [ ] ,
966
984
} ;
967
- let retry_strategy = Some ( BOLT_12_INVOICE_RETRY_STRATEGY ) ;
985
+ let retry_strategy = Some ( * retry_strategy ) ;
968
986
let payment_params = Some ( route_params. payment_params . clone ( ) ) ;
969
987
let ( retryable_payment, onion_session_privs) = self . create_pending_payment (
970
988
* payment_hash, recipient_onion. clone ( ) , None , & route,
@@ -1186,13 +1204,16 @@ impl OutboundPayments {
1186
1204
}
1187
1205
1188
1206
#[ 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 < ( ) , ( ) > {
1190
1210
let mut pending_outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1191
1211
match pending_outbounds. entry ( payment_id) {
1192
1212
hash_map:: Entry :: Occupied ( _) => Err ( ( ) ) ,
1193
1213
hash_map:: Entry :: Vacant ( entry) => {
1194
1214
entry. insert ( PendingOutboundPayment :: AwaitingInvoice {
1195
1215
timer_ticks_without_response : 0 ,
1216
+ retry_strategy,
1196
1217
} ) ;
1197
1218
1198
1219
Ok ( ( ) )
@@ -1667,9 +1688,11 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
1667
1688
} ,
1668
1689
( 5 , AwaitingInvoice ) => {
1669
1690
( 0 , timer_ticks_without_response, required) ,
1691
+ ( 2 , retry_strategy, required) ,
1670
1692
} ,
1671
1693
( 7 , InvoiceReceived ) => {
1672
1694
( 0 , payment_hash, required) ,
1695
+ ( 2 , retry_strategy, required) ,
1673
1696
} ,
1674
1697
) ;
1675
1698
@@ -1891,7 +1914,7 @@ mod tests {
1891
1914
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
1892
1915
1893
1916
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( ) ) ;
1895
1918
assert ! ( outbound_payments. has_pending_payments( ) ) ;
1896
1919
1897
1920
for _ in 0 ..INVOICE_REQUEST_TIMEOUT_TICKS {
@@ -1909,10 +1932,10 @@ mod tests {
1909
1932
) ;
1910
1933
assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
1911
1934
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( ) ) ;
1913
1936
assert ! ( outbound_payments. has_pending_payments( ) ) ;
1914
1937
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( ) ) ;
1916
1939
}
1917
1940
1918
1941
#[ test]
@@ -1922,7 +1945,7 @@ mod tests {
1922
1945
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
1923
1946
1924
1947
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( ) ) ;
1926
1949
assert ! ( outbound_payments. has_pending_payments( ) ) ;
1927
1950
1928
1951
outbound_payments. abandon_payment (
@@ -1950,7 +1973,7 @@ mod tests {
1950
1973
let outbound_payments = OutboundPayments :: new ( ) ;
1951
1974
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
1952
1975
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( ) ) ;
1954
1977
assert ! ( outbound_payments. has_pending_payments( ) ) ;
1955
1978
1956
1979
let created_at = now ( ) - DEFAULT_RELATIVE_EXPIRY ;
@@ -1996,7 +2019,7 @@ mod tests {
1996
2019
let outbound_payments = OutboundPayments :: new ( ) ;
1997
2020
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
1998
2021
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( ) ) ;
2000
2023
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2001
2024
2002
2025
let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
@@ -2049,7 +2072,7 @@ mod tests {
2049
2072
let outbound_payments = OutboundPayments :: new ( ) ;
2050
2073
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
2051
2074
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( ) ) ;
2053
2076
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2054
2077
2055
2078
let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
@@ -2149,7 +2172,7 @@ mod tests {
2149
2172
assert ! ( !outbound_payments. has_pending_payments( ) ) ;
2150
2173
assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
2151
2174
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( ) ) ;
2153
2176
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2154
2177
2155
2178
assert_eq ! (
0 commit comments