Skip to content

Commit cde9852

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 1cdec04 commit cde9852

File tree

2 files changed

+52
-52
lines changed

2 files changed

+52
-52
lines changed

lightning/src/ln/channelmanager.rs

+23-33
Original file line numberDiff line numberDiff line change
@@ -4233,9 +4233,10 @@ where
42334233
fn send_payment_for_verified_bolt12_invoice(&self, invoice: &Bolt12Invoice, payment_id: PaymentId) -> Result<(), Bolt12PaymentError> {
42344234
let best_block_height = self.best_block.read().unwrap().height;
42354235
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(self);
4236+
let features = self.bolt12_invoice_features();
42364237
self.pending_outbound_payments
42374238
.send_payment_for_bolt12_invoice(
4238-
invoice, payment_id, &self.router, self.list_usable_channels(),
4239+
invoice, payment_id, &self.router, self.list_usable_channels(), features,
42394240
|| self.compute_inflight_htlcs(), &self.entropy_source, &self.node_signer, &self,
42404241
&self.secp_ctx, best_block_height, &self.logger, &self.pending_events,
42414242
|args| self.send_payment_along_path(args)
@@ -10838,27 +10839,6 @@ where
1083810839
&self.logger, None, None, Some(invoice.payment_hash()),
1083910840
);
1084010841

10841-
let features = self.bolt12_invoice_features();
10842-
if invoice.invoice_features().requires_unknown_bits_from(&features) {
10843-
log_trace!(
10844-
logger, "Invoice requires unknown features: {:?}",
10845-
invoice.invoice_features(),
10846-
);
10847-
self.abandon_payment_with_reason(
10848-
payment_id, PaymentFailureReason::UnknownRequiredFeatures,
10849-
);
10850-
10851-
let error = InvoiceError::from(Bolt12SemanticError::UnknownRequiredFeatures);
10852-
let response = match responder {
10853-
Some(responder) => responder.respond(OffersMessage::InvoiceError(error)),
10854-
None => {
10855-
log_trace!(logger, "No reply path to send error: {:?}", error);
10856-
ResponseInstruction::NoResponse
10857-
},
10858-
};
10859-
return response;
10860-
}
10861-
1086210842
if self.default_configuration.manually_handle_bolt12_invoices {
1086310843
let event = Event::InvoiceReceived {
1086410844
payment_id, invoice, context, responder,
@@ -10867,24 +10847,34 @@ where
1086710847
return ResponseInstruction::NoResponse;
1086810848
}
1086910849

10870-
match self.send_payment_for_verified_bolt12_invoice(&invoice, payment_id) {
10850+
let error = match self.send_payment_for_verified_bolt12_invoice(
10851+
&invoice, payment_id,
10852+
) {
10853+
// Payments with UnknownRequiredFeatures error will already have been abandoned.
10854+
Err(Bolt12PaymentError::UnknownRequiredFeatures) => {
10855+
log_trace!(
10856+
logger, "Invoice requires unknown features: {:?}",
10857+
invoice.invoice_features()
10858+
);
10859+
InvoiceError::from(Bolt12SemanticError::UnknownRequiredFeatures)
10860+
},
1087110861
// Payments with SendingFailed error will already have been abandoned.
1087210862
Err(Bolt12PaymentError::SendingFailed(e)) => {
1087310863
log_trace!(logger, "Failed paying invoice: {:?}", e);
10874-
10875-
let err = InvoiceError::from_string(format!("{:?}", e));
10876-
match responder {
10877-
Some(responder) => responder.respond(OffersMessage::InvoiceError(err)),
10878-
None => {
10879-
log_trace!(logger, "No reply path to send error: {:?}", err);
10880-
ResponseInstruction::NoResponse
10881-
},
10882-
}
10864+
InvoiceError::from_string(format!("{:?}", e))
1088310865
},
1088410866
// Otherwise, don't abandon unknown, pending, or successful payments.
1088510867
Err(Bolt12PaymentError::UnexpectedInvoice)
1088610868
| Err(Bolt12PaymentError::DuplicateInvoice)
10887-
| Ok(()) => ResponseInstruction::NoResponse,
10869+
| Ok(()) => return ResponseInstruction::NoResponse,
10870+
};
10871+
10872+
match responder {
10873+
Some(responder) => responder.respond(OffersMessage::InvoiceError(error)),
10874+
None => {
10875+
log_trace!(logger, "No reply path to send error: {:?}", error);
10876+
ResponseInstruction::NoResponse
10877+
},
1088810878
}
1088910879
},
1089010880
#[cfg(async_payments)]

lightning/src/ln/outbound_payment.rs

+29-19
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)