-
Notifications
You must be signed in to change notification settings - Fork 160
Fix BOLT11 DuplicatePayment triggering on-chain fallback in unified payment #1038
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
ba5f712
e0fea6e
8261ca6
30aff00
9c2d37c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -287,9 +287,22 @@ impl UnifiedPayment { | |
|
|
||
| let payment_result = if let Ok(hrn) = HumanReadableName::from_encoded(uri_str) { | ||
| let hrn = maybe_wrap(hrn.clone()); | ||
| self.bolt12_payment.send_using_amount_inner(&offer, amount_msat.unwrap_or(0), None, None, route_parameters, Some(hrn)) | ||
| self.bolt12_payment.send_using_amount_inner( | ||
| &offer, | ||
| amount_msat.unwrap_or(0), | ||
| None, | ||
| None, | ||
| route_parameters, | ||
| Some(hrn), | ||
| ) | ||
| } else if let Some(amount_msat) = amount_msat { | ||
| self.bolt12_payment.send_using_amount(&offer, amount_msat, None, None, route_parameters) | ||
| self.bolt12_payment.send_using_amount( | ||
| &offer, | ||
| amount_msat, | ||
| None, | ||
| None, | ||
| route_parameters, | ||
| ) | ||
| } else { | ||
| self.bolt12_payment.send(&offer, None, None, route_parameters) | ||
| } | ||
|
|
@@ -304,14 +317,29 @@ impl UnifiedPayment { | |
| }, | ||
| PaymentMethod::LightningBolt11(invoice) => { | ||
| let invoice = maybe_wrap(invoice.clone()); | ||
| let payment_result = self.bolt11_invoice.send(&invoice, route_parameters) | ||
| .map_err(|e| { | ||
| let payment_result = self.bolt11_invoice.send(&invoice, route_parameters); | ||
|
|
||
| match payment_result { | ||
| Ok(payment_id) => { | ||
| return Ok(UnifiedPaymentResult::Bolt11 { payment_id }); | ||
| }, | ||
| // A duplicate payment already exists, so falling back to the | ||
| // on-chain method would pay the same invoice a second time. | ||
| Err(Error::DuplicatePayment) => { | ||
| log_error!(self.logger, "Failed to send BOLT11 invoice: DuplicatePayment. This is part of a unified payment. Aborting to avoid duplicate payment."); | ||
| return Err(Error::DuplicatePayment); | ||
| }, | ||
| // A persistence failure may occur after the Lightning payment has | ||
| // already been initiated with the ChannelManager. Falling back to | ||
| // the on-chain method in that case would double-pay, so we abort | ||
| // instead of proceeding to the next payment method. | ||
| Err(Error::PersistenceFailed) => { | ||
| log_error!(self.logger, "Failed to send BOLT11 invoice: PersistenceFailed. This is part of a unified payment. Aborting to avoid a potential duplicate payment."); | ||
| return Err(Error::PersistenceFailed); | ||
| }, | ||
| Err(e) => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like this error can be just a persistence error happening in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, persistence failures return a separate
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand your concern here, but that's a real pre-existing bug. It's also orthogonal to this PR, so I'll file it as a second follow-up rather than widen this change, as this PR is scoped to #1033.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seemed similar enough to me to fix here too. But indeed, this PR is an improvement on its own ofc. Can you post the follow-up issue here too?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually I now see the original issue cannot be closed with this PR, because it says: "It may also be worth reviewing other Lightning errors and separating them into: Maybe worth seeing if that's just a few more lines vs a bigger fix?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've audited every error the BOLT11 and BOLT12 legs of There are only two that indicate a payment was already initiated (or may have been): Now both errors surface after Every other error (PaymentSendingFailed, InvalidInvoice, route failures, etc.) is returned before that call succeeds, so falling back to on-chain is safe. So there are only two terminal errors, the rest safe.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here's how i want to resolve them errors:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good. That fully addresses the original issue. Curious though how much bolt12 is. If that is similarly minimal perhaps it can all be one PR, but up to you.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the change is essentially the same, but I'd like to keep it separate. I also have updated #1060 for Bolt12. |
||
| log_error!(self.logger, "Failed to send BOLT11 invoice: {:?}. This is part of a unified payment. Falling back to the on-chain transaction.", e); | ||
| e | ||
| }); | ||
|
|
||
| if let Ok(payment_id) = payment_result { | ||
| return Ok(UnifiedPaymentResult::Bolt11 { payment_id }); | ||
| }, | ||
| } | ||
| }, | ||
| PaymentMethod::OnChain(address) => { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.