@@ -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 ( ( ) )
@@ -1662,9 +1683,11 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
1662
1683
} ,
1663
1684
( 5 , AwaitingInvoice ) => {
1664
1685
( 0 , timer_ticks_without_response, required) ,
1686
+ ( 2 , retry_strategy, required) ,
1665
1687
} ,
1666
1688
( 7 , InvoiceReceived ) => {
1667
1689
( 0 , payment_hash, required) ,
1690
+ ( 2 , retry_strategy, required) ,
1668
1691
} ,
1669
1692
) ;
1670
1693
@@ -1895,7 +1918,7 @@ mod tests {
1895
1918
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
1896
1919
1897
1920
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( ) ) ;
1899
1922
assert ! ( outbound_payments. has_pending_payments( ) ) ;
1900
1923
1901
1924
for _ in 0 ..INVOICE_REQUEST_TIMEOUT_TICKS {
@@ -1915,10 +1938,10 @@ mod tests {
1915
1938
) ;
1916
1939
assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
1917
1940
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( ) ) ;
1919
1942
assert ! ( outbound_payments. has_pending_payments( ) ) ;
1920
1943
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( ) ) ;
1922
1945
}
1923
1946
1924
1947
#[ cfg( feature = "std" ) ]
@@ -1934,7 +1957,7 @@ mod tests {
1934
1957
let outbound_payments = OutboundPayments :: new ( ) ;
1935
1958
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
1936
1959
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( ) ) ;
1938
1961
assert ! ( outbound_payments. has_pending_payments( ) ) ;
1939
1962
1940
1963
let created_at = now ( ) - DEFAULT_RELATIVE_EXPIRY ;
@@ -1980,7 +2003,7 @@ mod tests {
1980
2003
let outbound_payments = OutboundPayments :: new ( ) ;
1981
2004
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
1982
2005
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( ) ) ;
1984
2007
assert ! ( outbound_payments. has_pending_payments( ) ) ;
1985
2008
1986
2009
let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
@@ -2033,7 +2056,7 @@ mod tests {
2033
2056
let outbound_payments = OutboundPayments :: new ( ) ;
2034
2057
let payment_id = PaymentId ( [ 0 ; 32 ] ) ;
2035
2058
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( ) ) ;
2037
2060
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2038
2061
2039
2062
let invoice = OfferBuilder :: new ( "foo" . into ( ) , recipient_pubkey ( ) )
@@ -2135,7 +2158,7 @@ mod tests {
2135
2158
assert ! ( !outbound_payments. has_pending_payments( ) ) ;
2136
2159
assert ! ( pending_events. lock( ) . unwrap( ) . is_empty( ) ) ;
2137
2160
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( ) ) ;
2139
2162
assert ! ( outbound_payments. has_pending_payments( ) ) ;
2140
2163
2141
2164
assert_eq ! (
0 commit comments