-
Notifications
You must be signed in to change notification settings - Fork 376
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
Support receiving async payments #3440
Draft
valentinewallace
wants to merge
23
commits into
lightningdevkit:main
Choose a base branch
from
valentinewallace:2024-12-async-payment-receive
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Support receiving async payments #3440
valentinewallace
wants to merge
23
commits into
lightningdevkit:main
from
valentinewallace:2024-12-async-payment-receive
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This still needs some work and tests but I opened it in case it's useful for reviewing #3408. |
valentinewallace
force-pushed
the
2024-12-async-payment-receive
branch
from
January 9, 2025 19:47
39f6a9e
to
904adf6
Compare
This argument will be asserted on in a future commit to ensure we obtain the intended `HTLCHandlingFailed::failed_next_destination` per HTLC failure.
This commit ensures all new incoming HTLCs going forward will have their onion decoded when they become fully committed to decide how we should proceed with each one. As a result, we'll obtain `HTLCHandlingFailed` events for _any_ failed HTLC that comes across a channel. Previously, we would evaluate the incoming HTLC within `can_accept_incoming_htlc` upon receiving it, but not yet committed, so we'd always have to account for it ourselves manually when checking certain HTLC limits. With this change, we no longer need to do so as it will already be accounted for within the pending HTLC stats computation. We will now start writing channels with the new serialization version (4), and we will still be able to downgrade back to the commit that introduced it since reading version 4 is supported. Note that existing pending inbound HTLCs may already have their resolution if they were received in a previous version of LDK. We must support those until we no longer allow downgrading beyond this commit.
Prior to this patch, we would take() the invoice request stored for AwaitingInvoice outbound payments when retrying sending the invoice request onion message. This doesn't work for async payments because we need to keep the invoice request stored for inclusion in the payment onion. Therefore, clone it instead of take()ing it.
Prior to this fix, we would attempt to mark outbound async payments as abandoned but silently fail because they were in state AwaitingInvoice, which the mark_abandoned utility doesn't currently work for. These payments would eventually be removed by the remove_stale_payments method, but there would be a delay in generating the PaymentFailed event. Move to manually removing the outbound payment entry.
Useful for creating payment paths for static invoices which are typically amount-less.
Will be useful for static invoices' blinded paths, which may have long expiries. Rather than having a default max_cltv_expiry, we now base it on the invoice expiry.
This context is stored in the blinded payment paths we put in static invoices and is useful to authenticate payments over these paths to the recipient. We can't reuse Bolt12OfferContext for this because we don't have access to the invoice request fields at static invoice creation time.
This context is included in static invoice's blinded message paths, provided back to us in HeldHtlcAvailable onion messages for blinded path authentication. In future work, we will check if this context is valid and respond with a ReleaseHeldHtlc message to release the upstream payment if so. We also add creation methods for the hmac used for authenticating said blinded path.
We can't use our regular offer creation util for receiving async payments because the recipient can't be relied on to be online to service invoice_requests. Therefore, add a new offer creation util that is parameterized by blinded message paths to another node on the network that *is* always-online and can serve static invoices on behalf of the often-offline recipient. Also add a utility for creating static invoices corresponding to these offers. See new utils' docs and BOLTs PR 1149 for more info.
Since adding support for creating static invoices from ChannelManager, it's easier to test these failure cases that went untested when we added support for paying static invoices.
Blinded keysend is only planned to be supported in the async payments context.
Blinded HTLCs are always failed back with the same error, so DRY the test code that fails them backwards. This util will also be used for async payments testing in upcoming commits.
Needed to authenticate that the held_htlc_available message is being sent over a reply path that we originally created and that isn't expired before we reply with release_held_htlc. This context will be used in upcoming commits when we add support for async receive.
Prior to this patch, if we received an expired static invoice we would delay surfacing the payment failure until after the recipient had come online and sent the release_held_htlc OM, which could be a long time later. Now, we'll detect that the invoice is expired as soon as it's received.
Here we bubble up the payment context into PendingHTLCRouting::ReceiveKeysend and check it when receiving a spontaneous payment prior to generating a claimable event. Prior to this patch, we would have accepted out-of-context keysends sent over blinded paths taken from our BOLT 12 invoices. As a side effect of this, our blinded keysend success test cases now fail, so those tests are now removed. Their coverage is re-added in future commits when we add support for async receive, meaning we're able to receive blinded keysends in the correct payment context.
Store an absolute expiry in blinded message contexts for inbound async payments. Without this, anyone with the path corresponding to this context is able to trivially ask if we're online forever.
If we receive a message that an HTLC is being held upstream for us, send a reply onion message back releasing it since we are online to receive the corresponding payment.
As part of receiving an async payment, we need to verify the sender's original invoice request. Therefore, add support for parsing the invreq contained in the onion and storing it in PendingHTLCForwards to prepare for when we add this verification in an upcoming commit. The invreq also needs to be bubbled up for inclusion in the PaymentClaimable event's PaymentPurpose.
After a lot of setup in prior commits, here we finally finish support for receiving HTLCs paid to static BOLT 12 invoices. It amounts to verifying the invoice request contained within the onion and generating the right PaymentPurpose for the claimable event.
Previously, this test util did not account for config overrides supplied at node creation time. Uncovered because it caused test nodes to be unable to forward over private channels created with this util because that is not the default.
In the previous commit we completed support for async receive from an always-online sender to an often-offline receiver, minus support for acting as the async receiver's always-online channel counterparty.
valentinewallace
force-pushed
the
2024-12-async-payment-receive
branch
from
January 9, 2025 20:50
904adf6
to
6f7fcba
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Finishes support for receiving async payments.
The last piece after this for the async-receive side is support for being the async receiver's LSP and serving invoices on their behalf.
Partially addresses #2298
Based on #3408, #3517
Also based on #2933, it enables the use of one of the test utils due to more uniform handling of HTLC receive failures.