Skip to content

Commit e4ca166

Browse files
committed
Move BOLT12 invoice features check
When handling a BOLT12 invoice, and invoice error is sent if the invoice contains unknown required features. However, since the payment is still in state AwaitingInvoice, abandoning it results in losing the reason since an InvoiceRequestFailed event would be generated. Move the check to PendingOutboundPayments such that the payment is first moved to state InvoiceReceived so that a PaymentFailed event is generated instead.
1 parent cfd0980 commit e4ca166

File tree

2 files changed

+51
-54
lines changed

2 files changed

+51
-54
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4238,9 +4238,10 @@ where
42384238
fn send_payment_for_verified_bolt12_invoice(&self, invoice: &Bolt12Invoice, payment_id: PaymentId) -> Result<(), Bolt12PaymentError> {
42394239
let best_block_height = self.best_block.read().unwrap().height;
42404240
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
4241+
let features = self.bolt12_invoice_features();
42414242
self.pending_outbound_payments
42424243
.send_payment_for_bolt12_invoice(
4243-
invoice, payment_id, &self.router, self.list_usable_channels(),
4244+
invoice, payment_id, &self.router, self.list_usable_channels(), features,
42444245
|| self.compute_inflight_htlcs(), &self.entropy_source, &self.node_signer, &self,
42454246
&self.secp_ctx, best_block_height, &self.logger, &self.pending_events,
42464247
|args| self.send_payment_along_path(args)
@@ -10845,27 +10846,6 @@ where
1084510846
&self.logger, None, None, Some(invoice.payment_hash()),
1084610847
);
1084710848

10848-
let features = self.bolt12_invoice_features();
10849-
if invoice.invoice_features().requires_unknown_bits_from(&features) {
10850-
log_trace!(
10851-
logger, "Invoice requires unknown features: {:?}",
10852-
invoice.invoice_features(),
10853-
);
10854-
self.abandon_payment_with_reason(
10855-
payment_id, PaymentFailureReason::UnknownRequiredFeatures,
10856-
);
10857-
10858-
let error = InvoiceError::from(Bolt12SemanticError::UnknownRequiredFeatures);
10859-
let response = match responder {
10860-
Some(responder) => responder.respond(OffersMessage::InvoiceError(error)),
10861-
None => {
10862-
log_trace!(logger, "No reply path to send error: {:?}", error);
10863-
ResponseInstruction::NoResponse
10864-
},
10865-
};
10866-
return response;
10867-
}
10868-
1086910849
if self.default_configuration.manually_handle_bolt12_invoices {
1087010850
let event = Event::InvoiceReceived {
1087110851
payment_id, invoice, context, responder,
@@ -10874,24 +10854,31 @@ where
1087410854
return ResponseInstruction::NoResponse;
1087510855
}
1087610856

10877-
match self.send_payment_for_verified_bolt12_invoice(&invoice, payment_id) {
10878-
// Payments with SendingFailed error will already have been abandoned.
10857+
let error = match self.send_payment_for_verified_bolt12_invoice(
10858+
&invoice, payment_id,
10859+
) {
10860+
Err(Bolt12PaymentError::UnknownRequiredFeatures) => {
10861+
log_trace!(
10862+
logger, "Invoice requires unknown features: {:?}",
10863+
invoice.invoice_features()
10864+
);
10865+
InvoiceError::from(Bolt12SemanticError::UnknownRequiredFeatures)
10866+
},
1087910867
Err(Bolt12PaymentError::SendingFailed(e)) => {
1088010868
log_trace!(logger, "Failed paying invoice: {:?}", e);
10881-
10882-
let err = InvoiceError::from_string(format!("{:?}", e));
10883-
match responder {
10884-
Some(responder) => responder.respond(OffersMessage::InvoiceError(err)),
10885-
None => {
10886-
log_trace!(logger, "No reply path to send error: {:?}", err);
10887-
ResponseInstruction::NoResponse
10888-
},
10889-
}
10869+
InvoiceError::from_string(format!("{:?}", e))
1089010870
},
10891-
// Otherwise, don't abandon unknown, pending, or successful payments.
1089210871
Err(Bolt12PaymentError::UnexpectedInvoice)
1089310872
| Err(Bolt12PaymentError::DuplicateInvoice)
10894-
| Ok(()) => ResponseInstruction::NoResponse,
10873+
| Ok(()) => return ResponseInstruction::NoResponse,
10874+
};
10875+
10876+
match responder {
10877+
Some(responder) => responder.respond(OffersMessage::InvoiceError(error)),
10878+
None => {
10879+
log_trace!(logger, "No reply path to send error: {:?}", error);
10880+
ResponseInstruction::NoResponse
10881+
},
1089510882
}
1089610883
},
1089710884
#[cfg(async_payments)]

lightning/src/ln/outbound_payment.rs

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::events::{self, PaymentFailureReason};
1919
use crate::ln::types::{PaymentHash, PaymentPreimage, PaymentSecret};
2020
use crate::ln::channel_state::ChannelDetails;
2121
use crate::ln::channelmanager::{EventCompletionAction, HTLCSource, PaymentId};
22+
use crate::ln::features::Bolt12InvoiceFeatures;
2223
use crate::ln::onion_utils;
2324
use crate::ln::onion_utils::{DecodedOnionFailure, HTLCFailReason};
2425
use crate::offers::invoice::Bolt12Invoice;
@@ -510,6 +511,8 @@ pub enum Bolt12PaymentError {
510511
UnexpectedInvoice,
511512
/// Payment for an invoice with the corresponding [`PaymentId`] was already initiated.
512513
DuplicateInvoice,
514+
/// The invoice was valid for the corresponding [`PaymentId`], but required unknown features.
515+
UnknownRequiredFeatures,
513516
/// The invoice was valid for the corresponding [`PaymentId`], but sending the payment failed.
514517
SendingFailed(RetryableSendFailure),
515518
}
@@ -783,9 +786,9 @@ impl OutboundPayments {
783786
R: Deref, ES: Deref, NS: Deref, NL: Deref, IH, SP, L: Deref
784787
>(
785788
&self, invoice: &Bolt12Invoice, payment_id: PaymentId, router: &R,
786-
first_hops: Vec<ChannelDetails>, inflight_htlcs: IH, entropy_source: &ES, node_signer: &NS,
787-
node_id_lookup: &NL, secp_ctx: &Secp256k1<secp256k1::All>, best_block_height: u32,
788-
logger: &L,
789+
first_hops: Vec<ChannelDetails>, features: Bolt12InvoiceFeatures, inflight_htlcs: IH,
790+
entropy_source: &ES, node_signer: &NS, node_id_lookup: &NL,
791+
secp_ctx: &Secp256k1<secp256k1::All>, best_block_height: u32, logger: &L,
789792
pending_events: &Mutex<VecDeque<(events::Event, Option<EventCompletionAction>)>>,
790793
send_payment_along_path: SP,
791794
) -> Result<(), Bolt12PaymentError>
@@ -819,6 +822,13 @@ impl OutboundPayments {
819822
hash_map::Entry::Vacant(_) => return Err(Bolt12PaymentError::UnexpectedInvoice),
820823
}
821824

825+
if invoice.invoice_features().requires_unknown_bits_from(&features) {
826+
self.abandon_payment(
827+
payment_id, PaymentFailureReason::UnknownRequiredFeatures, pending_events,
828+
);
829+
return Err(Bolt12PaymentError::UnknownRequiredFeatures);
830+
}
831+
822832
let mut payment_params = PaymentParameters::from_bolt12_invoice(&invoice);
823833

824834
// Advance any blinded path where the introduction node is our node.
@@ -1951,7 +1961,7 @@ mod tests {
19511961
use crate::events::{Event, PathFailure, PaymentFailureReason};
19521962
use crate::ln::types::PaymentHash;
19531963
use crate::ln::channelmanager::{PaymentId, RecipientOnionFields};
1954-
use crate::ln::features::{ChannelFeatures, NodeFeatures};
1964+
use crate::ln::features::{Bolt12InvoiceFeatures, ChannelFeatures, NodeFeatures};
19551965
use crate::ln::msgs::{ErrorAction, LightningError};
19561966
use crate::ln::outbound_payment::{Bolt12PaymentError, OutboundPayments, Retry, RetryableSendFailure, StaleExpiration};
19571967
#[cfg(feature = "std")]
@@ -2319,9 +2329,9 @@ mod tests {
23192329

23202330
assert_eq!(
23212331
outbound_payments.send_payment_for_bolt12_invoice(
2322-
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2323-
&&keys_manager, &EmptyNodeIdLookUp {}, &secp_ctx, 0, &&logger, &pending_events,
2324-
|_| panic!()
2332+
&invoice, payment_id, &&router, vec![], Bolt12InvoiceFeatures::empty(),
2333+
|| InFlightHtlcs::new(), &&keys_manager, &&keys_manager, &EmptyNodeIdLookUp {},
2334+
&secp_ctx, 0, &&logger, &pending_events, |_| panic!()
23252335
),
23262336
Err(Bolt12PaymentError::SendingFailed(RetryableSendFailure::PaymentExpired)),
23272337
);
@@ -2380,9 +2390,9 @@ mod tests {
23802390

23812391
assert_eq!(
23822392
outbound_payments.send_payment_for_bolt12_invoice(
2383-
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2384-
&&keys_manager, &EmptyNodeIdLookUp {}, &secp_ctx, 0, &&logger, &pending_events,
2385-
|_| panic!()
2393+
&invoice, payment_id, &&router, vec![], Bolt12InvoiceFeatures::empty(),
2394+
|| InFlightHtlcs::new(), &&keys_manager, &&keys_manager, &EmptyNodeIdLookUp {},
2395+
&secp_ctx, 0, &&logger, &pending_events, |_| panic!()
23862396
),
23872397
Err(Bolt12PaymentError::SendingFailed(RetryableSendFailure::RouteNotFound)),
23882398
);
@@ -2454,9 +2464,9 @@ mod tests {
24542464
assert!(!outbound_payments.has_pending_payments());
24552465
assert_eq!(
24562466
outbound_payments.send_payment_for_bolt12_invoice(
2457-
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2458-
&&keys_manager, &EmptyNodeIdLookUp {}, &secp_ctx, 0, &&logger, &pending_events,
2459-
|_| panic!()
2467+
&invoice, payment_id, &&router, vec![], Bolt12InvoiceFeatures::empty(),
2468+
|| InFlightHtlcs::new(), &&keys_manager, &&keys_manager, &EmptyNodeIdLookUp {},
2469+
&secp_ctx, 0, &&logger, &pending_events, |_| panic!()
24602470
),
24612471
Err(Bolt12PaymentError::UnexpectedInvoice),
24622472
);
@@ -2472,9 +2482,9 @@ mod tests {
24722482

24732483
assert_eq!(
24742484
outbound_payments.send_payment_for_bolt12_invoice(
2475-
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2476-
&&keys_manager, &EmptyNodeIdLookUp {}, &secp_ctx, 0, &&logger, &pending_events,
2477-
|_| Ok(())
2485+
&invoice, payment_id, &&router, vec![], Bolt12InvoiceFeatures::empty(),
2486+
|| InFlightHtlcs::new(), &&keys_manager, &&keys_manager, &EmptyNodeIdLookUp {},
2487+
&secp_ctx, 0, &&logger, &pending_events, |_| Ok(())
24782488
),
24792489
Ok(()),
24802490
);
@@ -2483,9 +2493,9 @@ mod tests {
24832493

24842494
assert_eq!(
24852495
outbound_payments.send_payment_for_bolt12_invoice(
2486-
&invoice, payment_id, &&router, vec![], || InFlightHtlcs::new(), &&keys_manager,
2487-
&&keys_manager, &EmptyNodeIdLookUp {}, &secp_ctx, 0, &&logger, &pending_events,
2488-
|_| panic!()
2496+
&invoice, payment_id, &&router, vec![], Bolt12InvoiceFeatures::empty(),
2497+
|| InFlightHtlcs::new(), &&keys_manager, &&keys_manager, &EmptyNodeIdLookUp {},
2498+
&secp_ctx, 0, &&logger, &pending_events, |_| panic!()
24892499
),
24902500
Err(Bolt12PaymentError::DuplicateInvoice),
24912501
);

0 commit comments

Comments
 (0)