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.
This commit is contained in:
Jeffrey Czyz 2024-07-24 17:05:42 -05:00
parent 144d4882ad
commit fbaf093ff4
No known key found for this signature in database
GPG key ID: 912EF12EA67705F5
2 changed files with 24 additions and 15 deletions

View file

@ -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) => {},

View file

@ -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
},
}