From fbaf093ff4d24ef7474c7e99d55b74f3f51abc21 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Wed, 24 Jul 2024 17:05:42 -0500 Subject: [PATCH] Don't use UserAbandoned reason for auto-failing A BOLT12 payment may be abandoned when handling the invoice or when receiving an InvoiceError message. When abandoning the payment, don't use UserAbandoned as the reason since that is meant for when the user calls ChannelManager::abandon_payment. --- lightning/src/events/mod.rs | 5 ++++- lightning/src/ln/channelmanager.rs | 34 ++++++++++++++++++------------ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/lightning/src/events/mod.rs b/lightning/src/events/mod.rs index 3972ea470..393acbc02 100644 --- a/lightning/src/events/mod.rs +++ b/lightning/src/events/mod.rs @@ -501,7 +501,7 @@ impl_writeable_tlv_based_enum!(InterceptNextHop, /// The reason the payment failed. Used in [`Event::PaymentFailed`]. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum PaymentFailureReason { - /// The intended recipient rejected our payment. + /// The intended recipient rejected our payment or invoice request. RecipientRejected, /// The user chose to abandon this payment by calling [`ChannelManager::abandon_payment`]. /// @@ -528,10 +528,13 @@ pub enum PaymentFailureReason { /// This error should generally never happen. This likely means that there is a problem with /// your router. UnexpectedError, + /// An invoice was received that required unknown features. + UnknownRequiredFeatures, } impl_writeable_tlv_based_enum!(PaymentFailureReason, (0, RecipientRejected) => {}, + (1, UnknownRequiredFeatures) => {}, (2, UserAbandoned) => {}, (4, RetriesExhausted) => {}, (6, PaymentExpired) => {}, diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 6b817e56b..17361a162 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -4275,8 +4275,12 @@ where /// /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice pub fn abandon_payment(&self, payment_id: PaymentId) { + self.abandon_payment_with_reason(payment_id, PaymentFailureReason::UserAbandoned) + } + + fn abandon_payment_with_reason(&self, payment_id: PaymentId, reason: PaymentFailureReason) { let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self); - self.pending_outbound_payments.abandon_payment(payment_id, PaymentFailureReason::UserAbandoned, &self.pending_events); + self.pending_outbound_payments.abandon_payment(payment_id, reason, &self.pending_events); } /// Send a spontaneous payment, which is a payment that does not require the recipient to have @@ -10729,17 +10733,6 @@ where let secp_ctx = &self.secp_ctx; let expanded_key = &self.inbound_payment_key; - let abandon_if_payment = |context| { - match context { - Some(OffersContext::OutboundPayment { payment_id, nonce, hmac }) => { - if signer::verify_payment_id(payment_id, hmac, nonce, expanded_key) { - self.abandon_payment(payment_id); - } - }, - _ => {}, - } - }; - match message { OffersMessage::InvoiceRequest(invoice_request) => { let responder = match responder { @@ -10859,7 +10852,9 @@ where logger, "Invoice requires unknown features: {:?}", invoice.invoice_features(), ); - abandon_if_payment(context); + self.abandon_payment_with_reason( + payment_id, PaymentFailureReason::UnknownRequiredFeatures, + ); let error = InvoiceError::from(Bolt12SemanticError::UnknownRequiredFeatures); let response = match responder { @@ -10916,10 +10911,21 @@ where Some(OffersContext::InboundPayment { payment_hash }) => Some(payment_hash), _ => None, }; + let logger = WithContext::from(&self.logger, None, None, payment_hash); log_trace!(logger, "Received invoice_error: {}", invoice_error); - abandon_if_payment(context); + match context { + Some(OffersContext::OutboundPayment { payment_id, nonce, hmac }) => { + if signer::verify_payment_id(payment_id, hmac, nonce, expanded_key) { + self.abandon_payment_with_reason( + payment_id, PaymentFailureReason::RecipientRejected, + ); + } + }, + _ => {}, + } + ResponseInstruction::NoResponse }, } -- 2.39.5