@@ -58,6 +58,15 @@ pub(crate) enum PendingOutboundPayment {
5858 Legacy {
5959 session_privs : HashSet < [ u8 ; 32 ] > ,
6060 } ,
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+ } ,
6170 AwaitingInvoice {
6271 expiration : StaleExpiration ,
6372 retry_strategy : Retry ,
@@ -201,6 +210,7 @@ impl PendingOutboundPayment {
201210 fn payment_hash ( & self ) -> Option < PaymentHash > {
202211 match self {
203212 PendingOutboundPayment :: Legacy { .. } => None ,
213+ PendingOutboundPayment :: AwaitingOffer { .. } => None ,
204214 PendingOutboundPayment :: AwaitingInvoice { .. } => None ,
205215 PendingOutboundPayment :: InvoiceReceived { payment_hash, .. } => Some ( * payment_hash) ,
206216 PendingOutboundPayment :: StaticInvoiceReceived { payment_hash, .. } => Some ( * payment_hash) ,
@@ -217,7 +227,8 @@ impl PendingOutboundPayment {
217227 PendingOutboundPayment :: Retryable { session_privs, .. } |
218228 PendingOutboundPayment :: Fulfilled { session_privs, .. } |
219229 PendingOutboundPayment :: Abandoned { session_privs, .. } => session_privs,
220- PendingOutboundPayment :: AwaitingInvoice { .. } |
230+ PendingOutboundPayment :: AwaitingOffer { .. } |
231+ PendingOutboundPayment :: AwaitingInvoice { .. } |
221232 PendingOutboundPayment :: InvoiceReceived { .. } |
222233 PendingOutboundPayment :: StaticInvoiceReceived { .. } => { debug_assert ! ( false ) ; return ; } ,
223234 } ) ;
@@ -258,7 +269,8 @@ impl PendingOutboundPayment {
258269 PendingOutboundPayment :: Abandoned { session_privs, .. } => {
259270 session_privs. remove ( session_priv)
260271 } ,
261- PendingOutboundPayment :: AwaitingInvoice { .. } |
272+ PendingOutboundPayment :: AwaitingOffer { .. } |
273+ PendingOutboundPayment :: AwaitingInvoice { .. } |
262274 PendingOutboundPayment :: InvoiceReceived { .. } |
263275 PendingOutboundPayment :: StaticInvoiceReceived { .. } => { debug_assert ! ( false ) ; false } ,
264276 } ;
@@ -288,7 +300,8 @@ impl PendingOutboundPayment {
288300 PendingOutboundPayment :: Retryable { session_privs, .. } => {
289301 session_privs. insert ( session_priv)
290302 } ,
291- PendingOutboundPayment :: AwaitingInvoice { .. } |
303+ PendingOutboundPayment :: AwaitingOffer { .. } |
304+ PendingOutboundPayment :: AwaitingInvoice { .. } |
292305 PendingOutboundPayment :: InvoiceReceived { .. } |
293306 PendingOutboundPayment :: StaticInvoiceReceived { .. } => { debug_assert ! ( false ) ; false } ,
294307 PendingOutboundPayment :: Fulfilled { .. } => false ,
@@ -322,6 +335,7 @@ impl PendingOutboundPayment {
322335 session_privs. len ( )
323336 } ,
324337 PendingOutboundPayment :: AwaitingInvoice { .. } => 0 ,
338+ PendingOutboundPayment :: AwaitingOffer { .. } => 0 ,
325339 PendingOutboundPayment :: InvoiceReceived { .. } => 0 ,
326340 PendingOutboundPayment :: StaticInvoiceReceived { .. } => 0 ,
327341 }
@@ -416,8 +430,9 @@ impl Display for PaymentAttempts {
416430 }
417431}
418432
419- /// How long before a [`PendingOutboundPayment::AwaitingInvoice`] should be considered stale and
420- /// candidate for removal in [`OutboundPayments::remove_stale_payments`].
433+ /// How long before a [`PendingOutboundPayment::AwaitingInvoice`] or
434+ /// [`PendingOutboundPayment::AwaitingOffer`] should be considered stale and candidate for removal
435+ /// in [`OutboundPayments::remove_stale_payments`].
421436#[ derive( Clone , Copy ) ]
422437pub ( crate ) enum StaleExpiration {
423438 /// Number of times [`OutboundPayments::remove_stale_payments`] is called.
@@ -1388,7 +1403,9 @@ impl OutboundPayments {
13881403 log_error ! ( logger, "Unable to retry payments that were initially sent on LDK versions prior to 0.0.102" ) ;
13891404 return
13901405 } ,
1391- PendingOutboundPayment :: AwaitingInvoice { .. } => {
1406+ PendingOutboundPayment :: AwaitingInvoice { .. }
1407+ | PendingOutboundPayment :: AwaitingOffer { .. } =>
1408+ {
13921409 log_error ! ( logger, "Payment not yet sent" ) ;
13931410 debug_assert ! ( false ) ;
13941411 return
@@ -1910,7 +1927,9 @@ impl OutboundPayments {
19101927 true
19111928 }
19121929 } ,
1913- PendingOutboundPayment :: AwaitingInvoice { expiration, .. } => {
1930+ PendingOutboundPayment :: AwaitingInvoice { expiration, .. }
1931+ | PendingOutboundPayment :: AwaitingOffer { expiration, .. } =>
1932+ {
19141933 let is_stale = match expiration {
19151934 StaleExpiration :: AbsoluteTimeout ( absolute_expiry) => {
19161935 * absolute_expiry <= duration_since_epoch
@@ -2096,22 +2115,28 @@ impl OutboundPayments {
20962115 let mut outbounds = self . pending_outbound_payments . lock ( ) . unwrap ( ) ;
20972116 if let hash_map:: Entry :: Occupied ( mut payment) = outbounds. entry ( payment_id) {
20982117 payment. get_mut ( ) . mark_abandoned ( reason) ;
2099- if let PendingOutboundPayment :: Abandoned { payment_hash, reason, .. } = payment. get ( ) {
2100- if payment. get ( ) . remaining_parts ( ) == 0 {
2118+ match payment. get ( ) {
2119+ PendingOutboundPayment :: Abandoned { payment_hash, reason, .. } => {
2120+ if payment. get ( ) . remaining_parts ( ) == 0 {
2121+ pending_events. lock ( ) . unwrap ( ) . push_back ( ( events:: Event :: PaymentFailed {
2122+ payment_id,
2123+ payment_hash : Some ( * payment_hash) ,
2124+ reason : * reason,
2125+ } , None ) ) ;
2126+ payment. remove ( ) ;
2127+ }
2128+ } ,
2129+ PendingOutboundPayment :: AwaitingInvoice { .. }
2130+ | PendingOutboundPayment :: AwaitingOffer { .. } =>
2131+ {
21012132 pending_events. lock ( ) . unwrap ( ) . push_back ( ( events:: Event :: PaymentFailed {
21022133 payment_id,
2103- payment_hash : Some ( * payment_hash ) ,
2104- reason : * reason,
2134+ payment_hash : None ,
2135+ reason : Some ( reason) ,
21052136 } , None ) ) ;
21062137 payment. remove ( ) ;
2107- }
2108- } else if let PendingOutboundPayment :: AwaitingInvoice { .. } = payment. get ( ) {
2109- pending_events. lock ( ) . unwrap ( ) . push_back ( ( events:: Event :: PaymentFailed {
2110- payment_id,
2111- payment_hash : None ,
2112- reason : Some ( reason) ,
2113- } , None ) ) ;
2114- payment. remove ( ) ;
2138+ } ,
2139+ _ => { } ,
21152140 }
21162141 }
21172142 }
@@ -2183,7 +2208,8 @@ impl OutboundPayments {
21832208 match self . pending_outbound_payments . lock ( ) . unwrap ( ) . entry ( payment_id) {
21842209 hash_map:: Entry :: Occupied ( mut entry) => {
21852210 let newly_added = match entry. get ( ) {
2186- PendingOutboundPayment :: AwaitingInvoice { .. } |
2211+ PendingOutboundPayment :: AwaitingOffer { .. } |
2212+ PendingOutboundPayment :: AwaitingInvoice { .. } |
21872213 PendingOutboundPayment :: InvoiceReceived { .. } |
21882214 PendingOutboundPayment :: StaticInvoiceReceived { .. } =>
21892215 {
@@ -2285,6 +2311,14 @@ impl_writeable_tlv_based_enum_upgradable!(PendingOutboundPayment,
22852311 ( 6 , route_params, required) ,
22862312 ( 8 , invoice_request, required) ,
22872313 } ,
2314+ // Added in 0.1. Prior versions will drop these outbounds on downgrade, which is safe because
2315+ // no HTLCs are in-flight.
2316+ ( 11 , AwaitingOffer ) => {
2317+ ( 0 , expiration, required) ,
2318+ ( 2 , retry_strategy, required) ,
2319+ ( 4 , max_total_routing_fee_msat, option) ,
2320+ ( 6 , amount_msats, required) ,
2321+ } ,
22882322) ;
22892323
22902324#[ cfg( test) ]
0 commit comments