Add PaymentFailureReason::InvoiceRequestRejected

Instead of re-using PaymentFailureReason::RecipientRejected, define a
new InvoiceRequestRejected variant for when an InvoiceError is received
instead of a Bolt12Invoice. This allows user to differentiate the cause
of the failure.
This commit is contained in:
Jeffrey Czyz 2024-08-06 18:33:51 -05:00
parent 457ba24ee5
commit 1563186c2b
No known key found for this signature in database
GPG key ID: 912EF12EA67705F5
3 changed files with 9 additions and 3 deletions

View file

@ -501,7 +501,7 @@ impl_writeable_tlv_based_enum!(InterceptNextHop,
/// The reason the payment failed. Used in [`Event::PaymentFailed`]. /// The reason the payment failed. Used in [`Event::PaymentFailed`].
#[derive(Clone, Copy, Debug, PartialEq, Eq)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum PaymentFailureReason { pub enum PaymentFailureReason {
/// The intended recipient rejected our payment or invoice request. /// The intended recipient rejected our payment.
RecipientRejected, RecipientRejected,
/// The user chose to abandon this payment by calling [`ChannelManager::abandon_payment`]. /// The user chose to abandon this payment by calling [`ChannelManager::abandon_payment`].
/// ///
@ -532,6 +532,10 @@ pub enum PaymentFailureReason {
UnknownRequiredFeatures, UnknownRequiredFeatures,
/// A [`Bolt12Invoice`] was not received in a reasonable amount of time. /// A [`Bolt12Invoice`] was not received in a reasonable amount of time.
InvoiceRequestExpired, InvoiceRequestExpired,
/// An [`InvoiceRequest`] for the payment was rejected by the recipient.
///
/// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
InvoiceRequestRejected,
} }
impl_writeable_tlv_based_enum!(PaymentFailureReason, impl_writeable_tlv_based_enum!(PaymentFailureReason,
@ -540,6 +544,7 @@ impl_writeable_tlv_based_enum!(PaymentFailureReason,
(2, UserAbandoned) => {}, (2, UserAbandoned) => {},
(3, InvoiceRequestExpired) => {}, (3, InvoiceRequestExpired) => {},
(4, RetriesExhausted) => {}, (4, RetriesExhausted) => {},
(5, InvoiceRequestRejected) => {},
(6, PaymentExpired) => {}, (6, PaymentExpired) => {},
(8, RouteNotFound) => {}, (8, RouteNotFound) => {},
(10, UnexpectedError) => {}, (10, UnexpectedError) => {},

View file

@ -10902,7 +10902,7 @@ where
Some(OffersContext::OutboundPayment { payment_id, nonce, hmac: Some(hmac) }) => { Some(OffersContext::OutboundPayment { payment_id, nonce, hmac: Some(hmac) }) => {
if signer::verify_payment_id(payment_id, hmac, nonce, expanded_key) { if signer::verify_payment_id(payment_id, hmac, nonce, expanded_key) {
self.abandon_payment_with_reason( self.abandon_payment_with_reason(
payment_id, PaymentFailureReason::RecipientRejected, payment_id, PaymentFailureReason::InvoiceRequestRejected,
); );
} }
}, },

View file

@ -1932,8 +1932,9 @@ fn fails_sending_invoice_without_blinded_payment_paths_for_offer() {
// Confirm that david drops this failed payment from his pending outbound payments. // Confirm that david drops this failed payment from his pending outbound payments.
match get_event!(david, Event::PaymentFailed) { match get_event!(david, Event::PaymentFailed) {
Event::PaymentFailed { payment_id: actual_payment_id, .. } => { Event::PaymentFailed { payment_id: actual_payment_id, reason, .. } => {
assert_eq!(payment_id, actual_payment_id); assert_eq!(payment_id, actual_payment_id);
assert_eq!(reason, Some(PaymentFailureReason::InvoiceRequestRejected));
}, },
_ => panic!("No Event::PaymentFailed"), _ => panic!("No Event::PaymentFailed"),
} }