@@ -502,6 +502,12 @@ impl_writeable_tlv_based_enum!(InterceptNextHop,
502502#[ derive( Clone , Copy , Debug , PartialEq , Eq ) ]
503503pub enum PaymentFailureReason {
504504 /// The intended recipient rejected our payment.
505+ ///
506+ /// Also used for [`UnknownRequiredFeatures`] and [`InvoiceRequestRejected`] when downgrading to
507+ /// version prior to 0.0.124.
508+ ///
509+ /// [`UnknownRequiredFeatures`]: Self::UnknownRequiredFeatures
510+ /// [`InvoiceRequestRejected`]: Self::InvoiceRequestRejected
505511 RecipientRejected ,
506512 /// The user chose to abandon this payment by calling [`ChannelManager::abandon_payment`].
507513 ///
@@ -517,7 +523,10 @@ pub enum PaymentFailureReason {
517523 /// The payment expired while retrying, based on the provided
518524 /// [`PaymentParameters::expiry_time`].
519525 ///
526+ /// Also used for [`InvoiceRequestExpired`] when downgrading to version prior to 0.0.124.
527+ ///
520528 /// [`PaymentParameters::expiry_time`]: crate::routing::router::PaymentParameters::expiry_time
529+ /// [`InvoiceRequestExpired`]: Self::InvoiceRequestExpired
521530 PaymentExpired ,
522531 /// We failed to find a route while retrying the payment.
523532 ///
@@ -528,12 +537,23 @@ pub enum PaymentFailureReason {
528537 /// This error should generally never happen. This likely means that there is a problem with
529538 /// your router.
530539 UnexpectedError ,
540+ /// An invoice was received that required unknown features.
541+ UnknownRequiredFeatures ,
542+ /// A [`Bolt12Invoice`] was not received in a reasonable amount of time.
543+ InvoiceRequestExpired ,
544+ /// An [`InvoiceRequest`] for the payment was rejected by the recipient.
545+ ///
546+ /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
547+ InvoiceRequestRejected ,
531548}
532549
533- impl_writeable_tlv_based_enum ! ( PaymentFailureReason ,
550+ impl_writeable_tlv_based_enum_upgradable ! ( PaymentFailureReason ,
534551 ( 0 , RecipientRejected ) => { } ,
552+ ( 1 , UnknownRequiredFeatures ) => { } ,
535553 ( 2 , UserAbandoned ) => { } ,
554+ ( 3 , InvoiceRequestExpired ) => { } ,
536555 ( 4 , RetriesExhausted ) => { } ,
556+ ( 5 , InvoiceRequestRejected ) => { } ,
537557 ( 6 , PaymentExpired ) => { } ,
538558 ( 8 , RouteNotFound ) => { } ,
539559 ( 10 , UnexpectedError ) => { } ,
@@ -769,22 +789,6 @@ pub enum Event {
769789 /// Sockets for connecting to the node.
770790 addresses : Vec < msgs:: SocketAddress > ,
771791 } ,
772- /// Indicates a request for an invoice failed to yield a response in a reasonable amount of time
773- /// or was explicitly abandoned by [`ChannelManager::abandon_payment`]. This may be for an
774- /// [`InvoiceRequest`] sent for an [`Offer`] or for a [`Refund`] that hasn't been redeemed.
775- ///
776- /// # Failure Behavior and Persistence
777- /// This event will eventually be replayed after failures-to-handle (i.e., the event handler
778- /// returning `Err(ReplayEvent ())`) and will be persisted across restarts.
779- ///
780- /// [`ChannelManager::abandon_payment`]: crate::ln::channelmanager::ChannelManager::abandon_payment
781- /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
782- /// [`Offer`]: crate::offers::offer::Offer
783- /// [`Refund`]: crate::offers::refund::Refund
784- InvoiceRequestFailed {
785- /// The `payment_id` to have been associated with payment for the requested invoice.
786- payment_id : PaymentId ,
787- } ,
788792 /// Indicates a [`Bolt12Invoice`] in response to an [`InvoiceRequest`] or a [`Refund`] was
789793 /// received.
790794 ///
@@ -876,12 +880,15 @@ pub enum Event {
876880 ///
877881 /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
878882 payment_id : PaymentId ,
879- /// The hash that was given to [`ChannelManager::send_payment`].
883+ /// The hash that was given to [`ChannelManager::send_payment`]. `None` if the payment failed
884+ /// before receiving an invoice when paying a BOLT12 [`Offer`].
880885 ///
881886 /// [`ChannelManager::send_payment`]: crate::ln::channelmanager::ChannelManager::send_payment
882- payment_hash : PaymentHash ,
887+ /// [`Offer`]: crate::offers::offer::Offer
888+ payment_hash : Option < PaymentHash > ,
883889 /// The reason the payment failed. This is only `None` for events generated or serialized
884- /// by versions prior to 0.0.115.
890+ /// by versions prior to 0.0.115, or when downgrading to a version with a reason that was
891+ /// added after.
885892 reason : Option < PaymentFailureReason > ,
886893 } ,
887894 /// Indicates that a path for an outbound payment was successful.
@@ -1552,10 +1559,34 @@ impl Writeable for Event {
15521559 } ,
15531560 & Event :: PaymentFailed { ref payment_id, ref payment_hash, ref reason } => {
15541561 15u8 . write ( writer) ?;
1562+ let ( payment_hash, invoice_received) = match payment_hash {
1563+ Some ( payment_hash) => ( payment_hash, true ) ,
1564+ None => ( & PaymentHash ( [ 0 ; 32 ] ) , false ) ,
1565+ } ;
1566+ let legacy_reason = match reason {
1567+ None => & None ,
1568+ // Variants available prior to version 0.0.124.
1569+ Some ( PaymentFailureReason :: RecipientRejected )
1570+ | Some ( PaymentFailureReason :: UserAbandoned )
1571+ | Some ( PaymentFailureReason :: RetriesExhausted )
1572+ | Some ( PaymentFailureReason :: PaymentExpired )
1573+ | Some ( PaymentFailureReason :: RouteNotFound )
1574+ | Some ( PaymentFailureReason :: UnexpectedError ) => reason,
1575+ // Variants introduced at version 0.0.124 or later. Prior versions fail to parse
1576+ // unknown variants, while versions 0.0.124 or later will use None.
1577+ Some ( PaymentFailureReason :: UnknownRequiredFeatures ) =>
1578+ & Some ( PaymentFailureReason :: RecipientRejected ) ,
1579+ Some ( PaymentFailureReason :: InvoiceRequestExpired ) =>
1580+ & Some ( PaymentFailureReason :: RetriesExhausted ) ,
1581+ Some ( PaymentFailureReason :: InvoiceRequestRejected ) =>
1582+ & Some ( PaymentFailureReason :: RecipientRejected ) ,
1583+ } ;
15551584 write_tlv_fields ! ( writer, {
15561585 ( 0 , payment_id, required) ,
1557- ( 1 , reason , option) ,
1586+ ( 1 , legacy_reason , option) ,
15581587 ( 2 , payment_hash, required) ,
1588+ ( 3 , invoice_received, required) ,
1589+ ( 5 , reason, option) ,
15591590 } )
15601591 } ,
15611592 & Event :: OpenChannelRequest { .. } => {
@@ -1634,12 +1665,6 @@ impl Writeable for Event {
16341665 ( 8 , funding_txo, required) ,
16351666 } ) ;
16361667 } ,
1637- & Event :: InvoiceRequestFailed { ref payment_id } => {
1638- 33u8 . write ( writer) ?;
1639- write_tlv_fields ! ( writer, {
1640- ( 0 , payment_id, required) ,
1641- } )
1642- } ,
16431668 & Event :: ConnectionNeeded { .. } => {
16441669 35u8 . write ( writer) ?;
16451670 // Never write ConnectionNeeded events as buffered onion messages aren't serialized.
@@ -1929,15 +1954,24 @@ impl MaybeReadable for Event {
19291954 let mut payment_hash = PaymentHash ( [ 0 ; 32 ] ) ;
19301955 let mut payment_id = PaymentId ( [ 0 ; 32 ] ) ;
19311956 let mut reason = None ;
1957+ let mut legacy_reason = None ;
1958+ let mut invoice_received: Option < bool > = None ;
19321959 read_tlv_fields ! ( reader, {
19331960 ( 0 , payment_id, required) ,
1934- ( 1 , reason , upgradable_option) ,
1961+ ( 1 , legacy_reason , upgradable_option) ,
19351962 ( 2 , payment_hash, required) ,
1963+ ( 3 , invoice_received, option) ,
1964+ ( 5 , reason, upgradable_option) ,
19361965 } ) ;
1966+ let payment_hash = match invoice_received {
1967+ Some ( invoice_received) => invoice_received. then ( || payment_hash) ,
1968+ None => ( payment_hash != PaymentHash ( [ 0 ; 32 ] ) ) . then ( || payment_hash) ,
1969+ } ;
1970+ let reason = reason. or ( legacy_reason) ;
19371971 Ok ( Some ( Event :: PaymentFailed {
19381972 payment_id,
19391973 payment_hash,
1940- reason,
1974+ reason : _init_tlv_based_struct_field ! ( reason , upgradable_option ) ,
19411975 } ) )
19421976 } ;
19431977 f ( )
@@ -2076,13 +2110,16 @@ impl MaybeReadable for Event {
20762110 } ;
20772111 f ( )
20782112 } ,
2113+ // This was Event::InvoiceRequestFailed prior to version 0.0.124.
20792114 33u8 => {
20802115 let mut f = || {
20812116 _init_and_read_len_prefixed_tlv_fields ! ( reader, {
20822117 ( 0 , payment_id, required) ,
20832118 } ) ;
2084- Ok ( Some ( Event :: InvoiceRequestFailed {
2119+ Ok ( Some ( Event :: PaymentFailed {
20852120 payment_id : payment_id. 0 . unwrap ( ) ,
2121+ payment_hash : None ,
2122+ reason : Some ( PaymentFailureReason :: InvoiceRequestExpired ) ,
20862123 } ) )
20872124 } ;
20882125 f ( )
0 commit comments