@@ -58,6 +58,15 @@ pub(crate) enum PendingOutboundPayment {
58
58
Legacy {
59
59
session_privs : HashSet < [ u8 ; 32 ] > ,
60
60
} ,
61
+ /// Used when we are waiting for an Offer to come back from a BIP 353 resolution
62
+ AwaitingOffer {
63
+ expiration : StaleExpiration ,
64
+ retry_strategy : Retry ,
65
+ max_total_routing_fee_msat : Option < u64 > ,
66
+ /// Human Readable Names-originated payments should always specify an explicit amount to
67
+ /// send up-front, which we track here and enforce once we receive the offer.
68
+ amount_msats : u64 ,
69
+ } ,
61
70
AwaitingInvoice {
62
71
expiration : StaleExpiration ,
63
72
retry_strategy : Retry ,
@@ -199,6 +208,7 @@ impl PendingOutboundPayment {
199
208
fn payment_hash ( & self ) -> Option < PaymentHash > {
200
209
match self {
201
210
PendingOutboundPayment :: Legacy { .. } => None ,
211
+ PendingOutboundPayment :: AwaitingOffer { .. } => None ,
202
212
PendingOutboundPayment :: AwaitingInvoice { .. } => None ,
203
213
PendingOutboundPayment :: InvoiceReceived { payment_hash, .. } => Some ( * payment_hash) ,
204
214
PendingOutboundPayment :: StaticInvoiceReceived { payment_hash, .. } => Some ( * payment_hash) ,
@@ -215,7 +225,8 @@ impl PendingOutboundPayment {
215
225
PendingOutboundPayment :: Retryable { session_privs, .. } |
216
226
PendingOutboundPayment :: Fulfilled { session_privs, .. } |
217
227
PendingOutboundPayment :: Abandoned { session_privs, .. } => session_privs,
218
- PendingOutboundPayment :: AwaitingInvoice { .. } |
228
+ PendingOutboundPayment :: AwaitingOffer { .. } |
229
+ PendingOutboundPayment :: AwaitingInvoice { .. } |
219
230
PendingOutboundPayment :: InvoiceReceived { .. } |
220
231
PendingOutboundPayment :: StaticInvoiceReceived { .. } => { debug_assert ! ( false ) ; return ; } ,
221
232
} ) ;
@@ -256,7 +267,8 @@ impl PendingOutboundPayment {
256
267
PendingOutboundPayment :: Abandoned { session_privs, .. } => {
257
268
session_privs. remove ( session_priv)
258
269
} ,
259
- PendingOutboundPayment :: AwaitingInvoice { .. } |
270
+ PendingOutboundPayment :: AwaitingOffer { .. } |
271
+ PendingOutboundPayment :: AwaitingInvoice { .. } |
260
272
PendingOutboundPayment :: InvoiceReceived { .. } |
261
273
PendingOutboundPayment :: StaticInvoiceReceived { .. } => { debug_assert ! ( false ) ; false } ,
262
274
} ;
@@ -286,7 +298,8 @@ impl PendingOutboundPayment {
286
298
PendingOutboundPayment :: Retryable { session_privs, .. } => {
287
299
session_privs. insert ( session_priv)
288
300
} ,
289
- PendingOutboundPayment :: AwaitingInvoice { .. } |
301
+ PendingOutboundPayment :: AwaitingOffer { .. } |
302
+ PendingOutboundPayment :: AwaitingInvoice { .. } |
290
303
PendingOutboundPayment :: InvoiceReceived { .. } |
291
304
PendingOutboundPayment :: StaticInvoiceReceived { .. } => { debug_assert ! ( false ) ; false } ,
292
305
PendingOutboundPayment :: Fulfilled { .. } => false ,
@@ -320,6 +333,7 @@ impl PendingOutboundPayment {
320
333
session_privs. len ( )
321
334
} ,
322
335
PendingOutboundPayment :: AwaitingInvoice { .. } => 0 ,
336
+ PendingOutboundPayment :: AwaitingOffer { .. } => 0 ,
323
337
PendingOutboundPayment :: InvoiceReceived { .. } => 0 ,
324
338
PendingOutboundPayment :: StaticInvoiceReceived { .. } => 0 ,
325
339
}
@@ -414,8 +428,9 @@ impl Display for PaymentAttempts {
414
428
}
415
429
}
416
430
417
- /// How long before a [`PendingOutboundPayment::AwaitingInvoice`] should be considered stale and
418
- /// candidate for removal in [`OutboundPayments::remove_stale_payments`].
431
+ /// How long before a [`PendingOutboundPayment::AwaitingInvoice`] or
432
+ /// [`PendingOutboundPayment::AwaitingOffer`] should be considered stale and candidate for removal
433
+ /// in [`OutboundPayments::remove_stale_payments`].
419
434
#[ derive( Clone , Copy ) ]
420
435
pub ( crate ) enum StaleExpiration {
421
436
/// Number of times [`OutboundPayments::remove_stale_payments`] is called.
@@ -1363,7 +1378,9 @@ impl OutboundPayments {
1363
1378
log_error ! ( logger, "Unable to retry payments that were initially sent on LDK versions prior to 0.0.102" ) ;
1364
1379
return
1365
1380
} ,
1366
- PendingOutboundPayment :: AwaitingInvoice { .. } => {
1381
+ PendingOutboundPayment :: AwaitingInvoice { .. }
1382
+ | PendingOutboundPayment :: AwaitingOffer { .. } =>
1383
+ {
1367
1384
log_error ! ( logger, "Payment not yet sent" ) ;
1368
1385
debug_assert ! ( false ) ;
1369
1386
return
@@ -1882,7 +1899,9 @@ impl OutboundPayments {
1882
1899
true
1883
1900
}
1884
1901
} ,
1885
- PendingOutboundPayment :: AwaitingInvoice { expiration, .. } => {
1902
+ PendingOutboundPayment :: AwaitingInvoice { expiration, .. }
1903
+ | PendingOutboundPayment :: AwaitingOffer { expiration, .. } =>
1904
+ {
1886
1905
let is_stale = match expiration {
1887
1906
StaleExpiration :: AbsoluteTimeout ( absolute_expiry) => {
1888
1907
* absolute_expiry <= duration_since_epoch
@@ -2068,22 +2087,28 @@ impl OutboundPayments {
2068
2087
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
2069
2088
if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( payment_id) {
2070
2089
payment. get_mut ( ) . mark_abandoned ( reason) ;
2071
- if let PendingOutboundPayment :: Abandoned { payment_hash, reason, .. } = payment. get ( ) {
2072
- if payment. get ( ) . remaining_parts ( ) == 0 {
2090
+ match payment. get ( ) {
2091
+ PendingOutboundPayment :: Abandoned { payment_hash, reason, .. } => {
2092
+ if payment. get ( ) . remaining_parts ( ) == 0 {
2093
+ pending_events. lock ( ) . unwrap ( ) . push_back ( ( events:: Event :: PaymentFailed {
2094
+ payment_id,
2095
+ payment_hash : Some ( * payment_hash) ,
2096
+ reason : * reason,
2097
+ } , None ) ) ;
2098
+ payment. remove ( ) ;
2099
+ }
2100
+ } ,
2101
+ PendingOutboundPayment :: AwaitingInvoice { .. }
2102
+ | PendingOutboundPayment :: AwaitingOffer { .. } =>
2103
+ {
2073
2104
pending_events. lock ( ) . unwrap ( ) . push_back ( ( events:: Event :: PaymentFailed {
2074
2105
payment_id,
2075
- payment_hash : Some ( * payment_hash ) ,
2076
- reason : * reason,
2106
+ payment_hash : None ,
2107
+ reason : Some ( reason) ,
2077
2108
} , None ) ) ;
2078
2109
payment. remove ( ) ;
2079
- }
2080
- } else if let PendingOutboundPayment :: AwaitingInvoice { .. } = payment. get ( ) {
2081
- pending_events. lock ( ) . unwrap ( ) . push_back ( ( events:: Event :: PaymentFailed {
2082
- payment_id,
2083
- payment_hash : None ,
2084
- reason : Some ( reason) ,
2085
- } , None ) ) ;
2086
- payment. remove ( ) ;
2110
+ } ,
2111
+ _ => { } ,
2087
2112
}
2088
2113
}
2089
2114
}
@@ -2154,7 +2179,8 @@ impl OutboundPayments {
2154
2179
match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
2155
2180
hash_map:: Entry :: Occupied ( mut entry) => {
2156
2181
let newly_added = match entry. get ( ) {
2157
- PendingOutboundPayment :: AwaitingInvoice { .. } |
2182
+ PendingOutboundPayment :: AwaitingOffer { .. } |
2183
+ PendingOutboundPayment :: AwaitingInvoice { .. } |
2158
2184
PendingOutboundPayment :: InvoiceReceived { .. } |
2159
2185
PendingOutboundPayment :: StaticInvoiceReceived { .. } =>
2160
2186
{
@@ -2254,6 +2280,14 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
2254
2280
( 4 , retry_strategy, required) ,
2255
2281
( 6 , route_params, required) ,
2256
2282
} ,
2283
+ // Added in 0.1. Prior versions will drop these outbounds on downgrade, which is safe because
2284
+ // no HTLCs are in-flight.
2285
+ ( 11 , AwaitingOffer ) => {
2286
+ ( 0 , expiration, required) ,
2287
+ ( 2 , retry_strategy, required) ,
2288
+ ( 4 , max_total_routing_fee_msat, option) ,
2289
+ ( 6 , amount_msats, required) ,
2290
+ } ,
2257
2291
) ;
2258
2292
2259
2293
#[ cfg( test) ]
0 commit comments