@@ -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 ///
@@ -878,8 +887,8 @@ pub enum Event {
878887 /// [`Offer`]: crate::offers::offer::Offer
879888 payment_hash : Option < PaymentHash > ,
880889 /// The reason the payment failed. This is only `None` for events generated or serialized
881- /// by versions prior to 0.0.115, or when downgrading to 0.0.124 or later with a reason that
882- /// was added after.
890+ /// by versions prior to 0.0.115, or when downgrading to a version with a reason that was
891+ /// added after.
883892 reason : Option < PaymentFailureReason > ,
884893 } ,
885894 /// Indicates that a path for an outbound payment was successful.
@@ -1554,11 +1563,30 @@ impl Writeable for Event {
15541563 Some ( payment_hash) => ( payment_hash, true ) ,
15551564 None => ( & PaymentHash ( [ 0 ; 32 ] ) , false ) ,
15561565 } ;
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+ } ;
15571584 write_tlv_fields ! ( writer, {
15581585 ( 0 , payment_id, required) ,
1559- ( 1 , reason , option) ,
1586+ ( 1 , legacy_reason , option) ,
15601587 ( 2 , payment_hash, required) ,
15611588 ( 3 , invoice_received, required) ,
1589+ ( 5 , reason, option) ,
15621590 } )
15631591 } ,
15641592 & Event :: OpenChannelRequest { .. } => {
@@ -1926,17 +1954,20 @@ impl MaybeReadable for Event {
19261954 let mut payment_hash = PaymentHash ( [ 0 ; 32 ] ) ;
19271955 let mut payment_id = PaymentId ( [ 0 ; 32 ] ) ;
19281956 let mut reason = None ;
1957+ let mut legacy_reason = None ;
19291958 let mut invoice_received: Option < bool > = None ;
19301959 read_tlv_fields ! ( reader, {
19311960 ( 0 , payment_id, required) ,
1932- ( 1 , reason , upgradable_option) ,
1961+ ( 1 , legacy_reason , upgradable_option) ,
19331962 ( 2 , payment_hash, required) ,
19341963 ( 3 , invoice_received, option) ,
1964+ ( 5 , reason, upgradable_option) ,
19351965 } ) ;
19361966 let payment_hash = match invoice_received {
19371967 Some ( invoice_received) => invoice_received. then ( || payment_hash) ,
19381968 None => ( payment_hash != PaymentHash ( [ 0 ; 32 ] ) ) . then ( || payment_hash) ,
19391969 } ;
1970+ let reason = reason. or ( legacy_reason) ;
19401971 Ok ( Some ( Event :: PaymentFailed {
19411972 payment_id,
19421973 payment_hash,
0 commit comments