@@ -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 ///
@@ -879,8 +888,8 @@ pub enum Event {
879888 payment_hash : Option < PaymentHash > ,
880889 /// The reason the payment failed. This is only `None` for events generated or serialized
881890 /// by versions prior to 0.0.115, when deserializing an `Event::InvoiceRequestFailed` (which
882- /// was removed in 0.0.124), or when downgrading to 0.0.124 or later with a reason that was
883- /// added after.
891+ /// was removed in 0.0.124), or when downgrading to a version with a reason that was added
892+ /// after.
884893 reason : Option < PaymentFailureReason > ,
885894 } ,
886895 /// Indicates that a path for an outbound payment was successful.
@@ -1555,11 +1564,30 @@ impl Writeable for Event {
15551564 Some ( payment_hash) => ( payment_hash, true ) ,
15561565 None => ( & PaymentHash ( [ 0 ; 32 ] ) , false ) ,
15571566 } ;
1567+ let legacy_reason = match reason {
1568+ None => & None ,
1569+ // Variants available prior to version 0.0.124.
1570+ Some ( PaymentFailureReason :: RecipientRejected )
1571+ | Some ( PaymentFailureReason :: UserAbandoned )
1572+ | Some ( PaymentFailureReason :: RetriesExhausted )
1573+ | Some ( PaymentFailureReason :: PaymentExpired )
1574+ | Some ( PaymentFailureReason :: RouteNotFound )
1575+ | Some ( PaymentFailureReason :: UnexpectedError ) => reason,
1576+ // Variants introduced at version 0.0.124 or later. Prior versions fail to parse
1577+ // unknown variants, while versions 0.0.124 or later will use None.
1578+ Some ( PaymentFailureReason :: UnknownRequiredFeatures ) =>
1579+ & Some ( PaymentFailureReason :: RecipientRejected ) ,
1580+ Some ( PaymentFailureReason :: InvoiceRequestExpired ) =>
1581+ & Some ( PaymentFailureReason :: RetriesExhausted ) ,
1582+ Some ( PaymentFailureReason :: InvoiceRequestRejected ) =>
1583+ & Some ( PaymentFailureReason :: RecipientRejected ) ,
1584+ } ;
15581585 write_tlv_fields ! ( writer, {
15591586 ( 0 , payment_id, required) ,
1560- ( 1 , reason , option) ,
1587+ ( 1 , legacy_reason , option) ,
15611588 ( 2 , payment_hash, required) ,
15621589 ( 3 , invoice_received, required) ,
1590+ ( 5 , reason, option) ,
15631591 } )
15641592 } ,
15651593 & Event :: OpenChannelRequest { .. } => {
@@ -1927,17 +1955,20 @@ impl MaybeReadable for Event {
19271955 let mut payment_hash = PaymentHash ( [ 0 ; 32 ] ) ;
19281956 let mut payment_id = PaymentId ( [ 0 ; 32 ] ) ;
19291957 let mut reason = None ;
1958+ let mut legacy_reason = None ;
19301959 let mut invoice_received: Option < bool > = None ;
19311960 read_tlv_fields ! ( reader, {
19321961 ( 0 , payment_id, required) ,
1933- ( 1 , reason , upgradable_option) ,
1962+ ( 1 , legacy_reason , upgradable_option) ,
19341963 ( 2 , payment_hash, required) ,
19351964 ( 3 , invoice_received, option) ,
1965+ ( 5 , reason, upgradable_option) ,
19361966 } ) ;
19371967 let payment_hash = match invoice_received {
19381968 Some ( invoice_received) => invoice_received. then ( || payment_hash) ,
19391969 None => ( payment_hash != PaymentHash ( [ 0 ; 32 ] ) ) . then ( || payment_hash) ,
19401970 } ;
1971+ let reason = reason. or ( legacy_reason) ;
19411972 Ok ( Some ( Event :: PaymentFailed {
19421973 payment_id,
19431974 payment_hash,
0 commit comments