Add a payment recipient abstraction#2480
Conversation
|
@pm47 @thomash-acinq I tagged you for review, but I think we should wait to integrate this only after the release, since it's a non-trivial refactoring, so there's no rush. It may be useful to have a look at #2481 and #2482 that build on top of this if you want to see the full picture. We can keep building on top of these branches until the release is out. |
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #2480 +/- ##
=======================================
Coverage 84.88% 84.89%
=======================================
Files 201 202 +1
Lines 15850 15905 +55
Branches 671 686 +15
=======================================
+ Hits 13454 13502 +48
- Misses 2396 2403 +7
🚀 New features to boost your workflow:
|
3550349 to
0a99d41
Compare
794c68d to
220d6a8
Compare
220d6a8 to
09cd42b
Compare
thomash-acinq
left a comment
There was a problem hiding this comment.
I had hoped the trampoline implementation details would be hidden inside Recipient but it creates confusing redundant fields: nodeId/targetNodeId and totalAmount/targetTotalAmount. You've explained why you did this but I don't think it's the right solution. And actually you haven't completely solved the problem of the base fee, it is still there in the targetMaxFee.
Since Multipart trampoline is not used anywhere today I think we should ignore it for now and add support for it in the router when the time is right.
I agree, I was hoping this could get simpler, but now I don't think it can (at least not without deep changes to But I'm completely open to exploring different designs, if you have ideas for different abstractions that can work without big changes to
I think you misunderstood what I meant by MPP aggregation issues, this is an issue that we have today (it isn't linked to splitting across multiple trampoline nodes). Let me detail the issue more, hopefully you can find ideas on how to address it better than what I currently did. If we want to get rid of the The issue arises when we split the payment to Ted, ie path-finding says we must split the payment across the following two routes:
What will really happen is that the payment will be split between Alice and Ted, but Ted will aggregate the two payments before relaying it, potentially with a single HTLC to Dave. If we get rid of the
I think we really need to handle this MPP aggregation at the trampoline node right now, because it is quite fundamental in the design and one of the important benefits of trampoline (we leverage this a lot in Phoenix to ensure that the trampoline node knows the total amount to be able to decide whether a new channel needs to be opened to carry the payment or not).
I don't know if that would even be the right approach, because I don't see how to do that inside the router while taking into account the fact that a split payment may have some routes that fail and other that work and are pending waiting for the complete amount to be sent. My current understanding is that we must handle that at the |
OK, I had missed this. I guess this solution is good enough for now then. |
09cd42b to
6152ea6
Compare
|
I've reworked the |
thomash-acinq
left a comment
There was a problem hiding this comment.
Great to finally converge on a solution we're both happy with.
We were previously directly creating onion payloads inside the various payment state machines and manipulating tlv fields. This was a layering violation that was somewhat ok because in most cases we only needed to create the onion payload for the recipient at the beginning of the payment flow and didn't need to modify it, except for a small change in the MPP case. This forced us to handle trampoline onions directly in the payment initiator and will not work for blinded payments, where we can only build the onion payload for the recipient after we've chosen the routes and how to split the amount. We clean this up by introducing payment recipients that abstract away the creation of onion payloads. This makes it much easier to integrate blinded payments. It also allows us to clean up the way we do trampoline payments and potentially support splitting across multiple trampoline routes (not included in this PR as this change isn't immediately needed). It also lets us simplify the MultiPartPaymentLifecycle FSM, by moving the logic of computing how much remains to be sent and what fee can be used to the route calculation component.
Thanks @thomash-acinq for the review.
9c42385 to
f7ec174
Compare
pm47
left a comment
There was a problem hiding this comment.
This is a light review, I'm missing context that led to the design decisions you made, but it LGTM.
This release introduces a few API changes: - `audit` now accepts `--count` and `--skip` parameters to limit the number of retrieved items (#2474, #2487) - `sendtoroute` removes the `--trampolineNodes` argument and implicitly uses a single trampoline hop (#2480) - `sendtoroute` now accept `--maxFeeMsat` to specify an upper bound of fees (#2626) - `payinvoice` always returns the payment result when used with `--blocking`, even when using MPP (#2525) - `node` returns high-level information about a remote node (#2568) - `channel-created` is a new websocket event that is published when a channel's funding transaction has been broadcast (#2567) - `channel-opened` websocket event was updated to contain the final `channel_id` and be published when a channel is ready to process payments (#2567) - `getsentinfo` can now be used with `--offer` to list payments sent to a specific offer - `listreceivedpayments` lists payments received by your node (#2607) - `closedchannels` lists closed channels. It accepts `--count` and `--skip` parameters to limit the number of retrieved items as well (#2642) - `cpfpbumpfees` can be used to unblock chains of unconfirmed transactions by creating a child transaction that pays a high fee (#1783)
We were previously directly creating onion payloads inside the various payment state machines and manipulating tlv fields. This was a layering violation that was somewhat ok because in most cases we only needed to create the onion payload for the recipient at the beginning of the payment flow and didn't need to modify it, except for a small change in the MPP case. When we introduced MPP and started modifying tlv payloads "on-the-fly" inside payment FSMs, I knew this wasn't very clean, but it probably wasn't worth a big refactoring yet.
The introduction of trampoline payments was another hint that something wasn't right with the model, because we had to handle trampoline onions directly in the payment initiator: again, we deferred a bigger refactoring because it was early and we weren't really sure what the right model would be to work with other future feature work.
The introduction of blinded payments is another feature where we run into this issue, because we can only build the onion payload for the recipient after we've chosen the routes (to insert the right encrypted recipient data) and how to split the amount, so our model of creating a
FinalPayloadat the beginning of the payment flow doesn't really fit.We clean this up by introducing payment recipients that abstract away the creation of onion payloads. This makes it much easier to integrate blinded payments. It also allows us to clean up the way we do trampoline payments and potentially support splitting across multiple trampoline routes (not included in this PR as this change isn't immediately needed).
ℹ️ It's important to note that our support for sending trampoline payments has always just been an imperfect implementation mostly meant to test the trampoline relay scenarios. It is a bit weird in some places, and when trampoline payments come closer to being standardized, we should introduce a dedicated FSM on top of the
MultiPartPaymentLifecycleFSM (that chooses how to split across multiple trampoline routes if needed and correctly handles trampolines fees/expiry retries). I don't think this should be done now and it seems to me that the current design will make it easy to implement when needed, but let me know if you feel otherwise. Another reason to defer this is that I'd like to first introduce support for blinded trampoline routes, which has a lot of benefits!