@@ -22,6 +22,7 @@ use crate::ln::features::Bolt12InvoiceFeatures;
22
22
use crate :: ln:: onion_utils;
23
23
use crate :: ln:: onion_utils:: { DecodedOnionFailure , HTLCFailReason } ;
24
24
use crate :: offers:: invoice:: Bolt12Invoice ;
25
+ use crate :: onion_message:: dns_resolution:: HumanReadableName ;
25
26
use crate :: routing:: router:: { BlindedTail , InFlightHtlcs , Path , PaymentParameters , Route , RouteParameters , Router } ;
26
27
use crate :: sign:: { EntropySource , NodeSigner , Recipient } ;
27
28
use crate :: util:: errors:: APIError ;
@@ -49,6 +50,16 @@ pub(crate) enum PendingOutboundPayment {
49
50
Legacy {
50
51
session_privs : HashSet < [ u8 ; 32 ] > ,
51
52
} ,
53
+ /// Used when we are waiting for an Offer to come back from a BIP 353 resolution
54
+ AwaitingOffer {
55
+ expiration : StaleExpiration ,
56
+ retry_strategy : Retry ,
57
+ max_total_routing_fee_msat : Option < u64 > ,
58
+ /// Human Readable Names-originated payments should always specify an explicit amount to
59
+ /// send up-front, which we track here and enforce once we receive the offer.
60
+ amount_msats : u64 ,
61
+ resolving_hrn : HumanReadableName ,
62
+ } ,
52
63
AwaitingInvoice {
53
64
expiration : StaleExpiration ,
54
65
retry_strategy : Retry ,
@@ -166,6 +177,7 @@ impl PendingOutboundPayment {
166
177
fn payment_hash ( & self ) -> Option < PaymentHash > {
167
178
match self {
168
179
PendingOutboundPayment :: Legacy { .. } => None ,
180
+ PendingOutboundPayment :: AwaitingOffer { .. } => None ,
169
181
PendingOutboundPayment :: AwaitingInvoice { .. } => None ,
170
182
PendingOutboundPayment :: InvoiceReceived { payment_hash, .. } => Some ( * payment_hash) ,
171
183
PendingOutboundPayment :: Retryable { payment_hash, .. } => Some ( * payment_hash) ,
@@ -182,6 +194,7 @@ impl PendingOutboundPayment {
182
194
PendingOutboundPayment :: Fulfilled { session_privs, .. } |
183
195
PendingOutboundPayment :: Abandoned { session_privs, .. } => session_privs,
184
196
PendingOutboundPayment :: AwaitingInvoice { .. } |
197
+ PendingOutboundPayment :: AwaitingOffer { .. } |
185
198
PendingOutboundPayment :: InvoiceReceived { .. } => { debug_assert ! ( false ) ; return ; } ,
186
199
} ) ;
187
200
let payment_hash = self . payment_hash ( ) ;
@@ -216,6 +229,7 @@ impl PendingOutboundPayment {
216
229
session_privs. remove ( session_priv)
217
230
} ,
218
231
PendingOutboundPayment :: AwaitingInvoice { .. } |
232
+ PendingOutboundPayment :: AwaitingOffer { .. } |
219
233
PendingOutboundPayment :: InvoiceReceived { .. } => { debug_assert ! ( false ) ; false } ,
220
234
} ;
221
235
if remove_res {
@@ -245,6 +259,7 @@ impl PendingOutboundPayment {
245
259
session_privs. insert ( session_priv)
246
260
} ,
247
261
PendingOutboundPayment :: AwaitingInvoice { .. } |
262
+ PendingOutboundPayment :: AwaitingOffer { .. } |
248
263
PendingOutboundPayment :: InvoiceReceived { .. } => { debug_assert ! ( false ) ; false } ,
249
264
PendingOutboundPayment :: Fulfilled { .. } => false ,
250
265
PendingOutboundPayment :: Abandoned { .. } => false ,
@@ -277,6 +292,7 @@ impl PendingOutboundPayment {
277
292
session_privs. len ( )
278
293
} ,
279
294
PendingOutboundPayment :: AwaitingInvoice { .. } => 0 ,
295
+ PendingOutboundPayment :: AwaitingOffer { .. } => 0 ,
280
296
PendingOutboundPayment :: InvoiceReceived { .. } => 0 ,
281
297
}
282
298
}
@@ -370,8 +386,9 @@ impl Display for PaymentAttempts {
370
386
}
371
387
}
372
388
373
- /// How long before a [`PendingOutboundPayment::AwaitingInvoice`] should be considered stale and
374
- /// candidate for removal in [`OutboundPayments::remove_stale_payments`].
389
+ /// How long before a [`PendingOutboundPayment::AwaitingInvoice`] or
390
+ /// [`PendingOutboundPayment::AwaitingOffer`] should be considered stale and candidate for removal
391
+ /// in [`OutboundPayments::remove_stale_payments`].
375
392
#[ derive( Clone , Copy ) ]
376
393
pub ( crate ) enum StaleExpiration {
377
394
/// Number of times [`OutboundPayments::remove_stale_payments`] is called.
@@ -1165,7 +1182,9 @@ impl OutboundPayments {
1165
1182
log_error ! ( logger, "Unable to retry payments that were initially sent on LDK versions prior to 0.0.102" ) ;
1166
1183
return
1167
1184
} ,
1168
- PendingOutboundPayment :: AwaitingInvoice { .. } => {
1185
+ PendingOutboundPayment :: AwaitingInvoice { .. }
1186
+ | PendingOutboundPayment :: AwaitingOffer { .. } =>
1187
+ {
1169
1188
log_error ! ( logger, "Payment not yet sent" ) ;
1170
1189
debug_assert ! ( false ) ;
1171
1190
return
@@ -1675,7 +1694,9 @@ impl OutboundPayments {
1675
1694
true
1676
1695
}
1677
1696
} ,
1678
- PendingOutboundPayment :: AwaitingInvoice { expiration, .. } => {
1697
+ PendingOutboundPayment :: AwaitingInvoice { expiration, .. }
1698
+ | PendingOutboundPayment :: AwaitingOffer { expiration, .. } =>
1699
+ {
1679
1700
let is_stale = match expiration {
1680
1701
StaleExpiration :: AbsoluteTimeout ( absolute_expiry) => {
1681
1702
* absolute_expiry <= duration_since_epoch
@@ -1845,22 +1866,28 @@ impl OutboundPayments {
1845
1866
let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
1846
1867
if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( payment_id) {
1847
1868
payment. get_mut ( ) . mark_abandoned ( reason) ;
1848
- if let PendingOutboundPayment :: Abandoned { payment_hash, reason, .. } = payment. get ( ) {
1849
- if payment. get ( ) . remaining_parts ( ) == 0 {
1869
+ match payment. get ( ) {
1870
+ PendingOutboundPayment :: Abandoned { payment_hash, reason, .. } => {
1871
+ if payment. get ( ) . remaining_parts ( ) == 0 {
1872
+ pending_events. lock ( ) . unwrap ( ) . push_back ( ( events:: Event :: PaymentFailed {
1873
+ payment_id,
1874
+ payment_hash : Some ( * payment_hash) ,
1875
+ reason : * reason,
1876
+ } , None ) ) ;
1877
+ payment. remove ( ) ;
1878
+ }
1879
+ } ,
1880
+ PendingOutboundPayment :: AwaitingInvoice { .. }
1881
+ | PendingOutboundPayment :: AwaitingOffer { .. } =>
1882
+ {
1850
1883
pending_events. lock ( ) . unwrap ( ) . push_back ( ( events:: Event :: PaymentFailed {
1851
1884
payment_id,
1852
- payment_hash : Some ( * payment_hash ) ,
1853
- reason : * reason,
1885
+ payment_hash : None ,
1886
+ reason : Some ( reason) ,
1854
1887
} , None ) ) ;
1855
1888
payment. remove ( ) ;
1856
- }
1857
- } else if let PendingOutboundPayment :: AwaitingInvoice { .. } = payment. get ( ) {
1858
- pending_events. lock ( ) . unwrap ( ) . push_back ( ( events:: Event :: PaymentFailed {
1859
- payment_id,
1860
- payment_hash : None ,
1861
- reason : Some ( reason) ,
1862
- } , None ) ) ;
1863
- payment. remove ( ) ;
1889
+ } ,
1890
+ _ => { } ,
1864
1891
}
1865
1892
}
1866
1893
}
@@ -1935,6 +1962,13 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
1935
1962
( 2 , retry_strategy, required) ,
1936
1963
( 4 , max_total_routing_fee_msat, option) ,
1937
1964
} ,
1965
+ ( 9 , AwaitingOffer ) => {
1966
+ ( 0 , expiration, required) ,
1967
+ ( 2 , retry_strategy, required) ,
1968
+ ( 4 , max_total_routing_fee_msat, option) ,
1969
+ ( 6 , amount_msats, required) ,
1970
+ ( 8 , resolving_hrn, required) ,
1971
+ } ,
1938
1972
) ;
1939
1973
1940
1974
#[ cfg( test) ]
0 commit comments