-
Notifications
You must be signed in to change notification settings - Fork 366
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
Allow Asynchronously responding to Invoice Request #3318
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3318 +/- ##
==========================================
- Coverage 89.64% 89.57% -0.07%
==========================================
Files 126 126
Lines 102676 102849 +173
Branches 102676 102849 +173
==========================================
+ Hits 92045 92132 +87
- Misses 7912 7987 +75
- Partials 2719 2730 +11 ☔ View full report in Codecov by Sentry. |
// Make sure that invoice_request amount and custom amount are not present at the same time. | ||
if invoice_request.amount().is_some() && custom_amount_msats.is_some() { | ||
return Err(Bolt12ResponseError::UnexpectedAmount) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this redundant with the check in the builder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The check in the builder does trigger a Bolt12SemanticError
when this case comes up. But this feels more like a user-side error than a problem with the InvoiceRequest
itself.
To make sure we generate the right type of error and avoid sending an InvoiceError
in this situation, I've added this extra check to handle it properly.
let amount_msats = match InvoiceBuilder::<DerivedSigningPubkey>::amount_msats( | ||
&invoice_request.inner, custom_amount_msats | ||
) { | ||
Ok(amount_msats) => amount_msats, | ||
Err(error) => return Err(Bolt12ResponseError::SemanticError(error)), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this also called in the builder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!
But AFAIU, this is also called here so that the amount_msats
value can be used with the create_inbound_payment
and create_blinded_payment_paths
functions.
1. Till now this UserConfig option was used to indicate whether the user wants to handles the payment for received Bolt12Invoices manually. 2. The future commits expand it's use case, so that it can also be used to indicate whether the user wants to handle response to the received Invoice Request manually as well. 3. Rename this UserConfig appropriately to better represent its use case.
1. This event will be triggered when user enables manual handling of BOLT12 Messages. 2. With this event they can do some preprocessing on their end to make sure if they want to continue with this inbound payment. 3. For example, this can be used by the user to do the currency conversion on their end and respond to invoice request accordingly.
c9f52f4
to
3b5af51
Compare
- Also move event generation after invoice request verification.
Introduce a new category of Bolt12 errors that contains the error generated while trying to respond asynchronously to Bolt12 messages.
1. The amount_msats function first checks if any amount is given with the invoice requests, and defaults to using offer's amount if it's absent. 2. This can be a problem if the amount in offer was represent as a Currency. 3. Update amount_msats to take in an optional custom amount which can be used in case amount if absent in Invoice Request. 4. This update will be utilised in the following commits to set custom amount_msats when responding to Invoice Request Asychronously.
Custom amount should only be provided if only the offer is denomiated in currency, and no amount is provided in invoice request. This is done so that the use of Custom Amount can be more specific to the case when Offer is denomiated in Currency.
1. Introduce a set of private functions that handles the creation of response for a received Invoice Request. 2. This helps refactor the the logic of response creation in a single function. 3. This will be used in the following commit to send response for invoice_request asynchronously.
3b5af51
to
9b4daa4
Compare
I'm kinda skeptical of the approach of pushing yet more message handling out through the event handling interface. Looking back I'm really not a fan of the approach we took with
|
I also regret not doing it this way initially, since I assume this would have reduced the code in LNDK rather nontrivially :/ |
I'll need a more concrete description of this to make sure that I understand what you are proposing. Let's call the refactored out struct So, in practice, users would simply implement a small trait and parameterize IIUC, the logic for constructing an invoice would still reside in Does all of that sound right?
Hmm... does it make it that much simpler? The above can be accomplished without rust-lightning/lightning/src/ln/channelmanager.rs Lines 11138 to 11155 in a952d2d
rust-lightning/lightning/src/ln/channelmanager.rs Lines 11240 to 11243 in a952d2d
Or do you also want to move the Let me know if I misunderstood anything. |
I'll be honest I hadn't thought it all the way through, but, no I do think we should have the We could have the |
We also have I'm actually more in favor of this now, especially if allows us to reduce the amount of code in |
|
@TheBlueMatt I was thinking about this a bit more. For the Fedimint case, the gateway will need to communicate with the client before responding or possibly (depending on the ultimate approach) wait for the federation to sign, IIUC. That would mean we'd either have to block waiting for the response or expose an asynchronous interface after all. This probably could be avoided for the currency use case if exchange rates are cached, though. We could still refactor but seems we'd need to allow for asynchronous responses? |
Hmm, given our current retry logic we could easily move it to this new struct. If we substantially change it that might have to change for DoS risks, but probably we won't hugely change it.
Maybe the trait from the |
Introduce a new event and set of supporting functions to allow flexibility in responding asynchronously to a received invoice request.
This PR provides foundational work for further improvements in future. For example, this allows supporting Offers created in currency denomination, as a user can do appropriate pre-processing for a received InvoiceRequest, before sending an Invoice for it.