-
Notifications
You must be signed in to change notification settings - Fork 2.2k
multi: update the switch+router to be aware of the new TLV EOB format #3362
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
multi: update the switch+router to be aware of the new TLV EOB format #3362
Conversation
joostjager
left a comment
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.
Did an initial pass.
My main comment is about the reach of the tlv types. The way I look at them is as a protocol level data structure. In this PR tlv records are exposed all the way to the rpc interface. I have a feeling that we may run into undesirable situations in the future with that.
Are there real downsides to decoding the eob payload in a regular go struct directly after we receive it? If there is a performance benefit, I wouldn't expect it to be significant.
The same can be send for calls like
Passing records or blobs around leaves the decoding to the furthest endpoint, that being the caller. On the RPC level we don't really care what it is, only once it reaches say the invoice registry does it actually need manifest that into a concrete struct type (like a payment shard). |
Yes, that is clarified now. I didn't realize it could be used to pass completely custom data to the recipient. |
I checked off this box as I think we can leave it to anther PR, as in order for us to be consistent (including this information for all accept calls), we need to persist this information somewhere. |
|
Also noting that for the onion section, we need to use a different integer encoding that leaves off the length of the total integer. The |
|
Pushed up a new version with some bug fixes as fixup commits. I've also modified the integration tests to be able to test the old+new nodes. To do this, we've now gained a new |
f3d6e4b to
5c595cc
Compare
5c595cc to
9899fe3
Compare
|
Pushed up a new version that uses the proper truncated integers now that the TLV PR has been merged into master. During testing I found a bug in the When updating the tests in the |
9899fe3 to
f77f56e
Compare
|
Pushed up another version rebasing of the bug fix in the |
tlv/onion_types.go
Outdated
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.
perhaps define these in invoices, since there's no global tlv namespace?
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.
Yeah I had this in a few other places, then settled on this since the package doesn't import any other internal packages other than for benchmarks. I ran into an import cycle earlier on when it was in the switch as an example.
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.
might be worth making a subpackage of tlv, e.g. tlv/onion just for defining these constants. just a thought
lntest/itest/lnd_test.go
Outdated
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.
should we run this test with both legacy and non-legacy payloads? possibly even using a mixed route?
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 route is already mixed as Dave it the only one using the legacy protocol. Or do you mean an entire all legacy or modern route?
f77f56e to
ba1788b
Compare
|
New version pushed up that includes a migration for existing payment attempts, and fixes a bug in the old serialization. I think this is ready for final review now! |
ba1788b to
5265dae
Compare
|
5265dae to
1bac725
Compare
|
The |
|
Found the cause of the |
4593820 to
70a1ec5
Compare
|
I haven't been provided a compelling reason to remove the RPC functionality from the PR within the correspondence of this PR so far. As for the resolver functionality, there's no known code path that will result in us needing information there. When that code path is added (mmp, amp), then we can resolve that as I mentioned above by supplementing the resolver as we do when we need to obtain additional context from the channel/commitment. |
|
A compelling reason for me is that we shouldn't merge functionality that has no practical use. Without the invoice registry handling the custom records, it has no practical use. Afaik there is no time line for the follow up that makes this functionality complete, so it may remain incomplete for a while. |
|
The functionality has near term practical use. The timeline for following up is this coming release. It's possible on this very day to create a branch dependent on this PR this beings to utilize this functionality. |
70a1ec5 to
6b5b887
Compare
|
I think I have expressed my opinion about pr scope clear enough. I still see no reason why we should merge a partial implementation now and not as part of that near term follow up. |
|
Merging this partial implementation, which makes no irreversible decisions on potential design points that may arise during the follows won't impede them at all. We have no golden rule against proceeding with partial versions of a solution when the follow ups are direct and imminent. Implementing all the planned follow ups in this PR would result in it being massive, as the planned follow ups span multiple sub-systems and even implement a new payment type within the system. |
|
There is no golden rule, but a well-scoped pr is better than a pr with a boundary that isn't as clearly defined. It is not a blocker, but imo still something to acknowledge and keep in mind for future prs. I am not advocating for fixing everything in this pr which is already large, but to do the opposite and slim it down. In the tlv payload domain, there were multiple scopes possible for this pr:
The pr currently implements 1, 2 and a part of 3. For multi-path payments, we need 1 and 3. |
|
PTAL @cfromknecht |
6b5b887 to
9a999be
Compare
cfromknecht
left a comment
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.
LGTM 🍾
joostjager
left a comment
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.
There are still a few open comments buried in the long discussion of this pr. I think there is some value left in those, but nothing that cannot be addressed later.
LGTM! 🚀
9a999be to
6f1b250
Compare
In this commit, we add two new method so the `Record` struct: Type() and Encode(). These are useful when a caller is handling a record and may not know its underlying type and may need to encode a record in isolation.
In this commit, we extend the Hop struct to carry an arbitrary set of TLV values, and add a new field that allows us to distinguish between the modern and legacy TLV payload. We add a new `PackPayload` method that will be used to encode the combined required routing TLV fields along any set of TLV fields that were specified as part of path finding. Finally, the `ToSphinxPath` has been extended to be able to recognize if a hop needs the modern, or legacy payload.
In this commit, we extend the path finding to be able to recognize when a node needs the new TLV format, or the legacy format based on the feature bits they expose. We also extend the `LightningPayment` struct to allow the caller to specify an arbitrary set of TLV records which can be used for a number of use-cases including various variants of spontaneous payments.
In this commit, we add a new field to the Hop proto to allow callers to be able to specify TLV records for the SendToRoute call, and also to be able to display TLV records that were used during regular path finding. We also update SendPayment to support dest TLV records.
…fields We also include a migration for the existing routes stored on disk.
… registry In this commit, we update the `HopIterator` to gain awareness of the new TLV hop payload. The default `HopIterator` will now hide the details of the TLV from the caller, and return the same `ForwardingInfo` struct in a uniform manner. We also add a new method: `ExtraOnionBlob` to allow the caller to obtain the raw EOB (the serialized TLV stream) to pass around. Within the link, we'll now pass the EOB information into the invoice registry. This allows the registry to parse out any additional information from the EOB that it needs to settle the payment, such as a preimage shard in the AMP case.
…gacy onion In this commit, we add a new build tag protected sub-config for legacy protocol features. The goal of this addition is to be able to default to new feature within lnd, but expose hooks at the config level to allow integration tests to force the old behavior to ensure that we're able to support both the old+new versions.
… pay test In this commit, we force Dave to use the legacy onion payload for the multi-hop test to ensure that we're able to properly mix the old and new formats, and have all nodes properly decode+forward the HTLC.
6f1b250 to
b1aea41
Compare
|
Fixed a bug in the migration, needed to check for the existence of the mission control bucket (as 0.7.1 didn't have that present for example). Confirmed the migration is able to be applied without issue now! |
This is a preparatory PR meant to lay the remaining ground work for our AMP implementation in
lnd. This PR builds on top of #3061 and lightningnetwork/lightning-onion#38.routing+channeldbExtensionsAfter this PR the router is able to preferentially provide a hop with the new hop payload format based on its set of known feature bits. Clients to the router are now also able to provide an arbitrary set of KV pairs for the final destination, with path finding failing early if it's known that the destination doesn't support this new update.
The
Hopstruct now carries TLV records that may have been assigned during the path finding phase, with features in mind such as rendezvous routing. Along the way we also update thelnrpcprotos to be able to accept these new TLV fields in order to allow the callers of theSendToRoutecall to provide arbitrary TLV pairs.We also update the payment serialization for the
Hopstructs to be aware of the new fields. In this PR we opted to append the fields to the end of the existingHopserialization. However, given that this PR depends on the new TLV construct, we very well could add the new set of fields as composite TLV records within the database. However, it would seem preferable to implement a unified TLV-based optional field abstraction within thechanneldbpackage rather than introducing one here to ensure we're all comfortable with the design.invoices+htlcswitchExtensionsWhen parsing the forwarding information from a raw onion packet, we're now able to pull the new TLV encoded information as well as the legacy packed info within a unified call. As a result, the caller doesn't need to know what type of onion was provided, since in the near future both formats will be in flight.
The primary
InvoiceRegistrystruct has been updated to accept an optionaleobparameter. This will include the entire TLV payload, which allows the registry to extract any additional information it needs to settle a payment such as payment shards for AMP. We'll likely also want to expose this EOB information over the RPC invoice acceptance calls as well, since they give developers an additional level of flexibility to roll out their own application level protocols.====
TODO
Include the new EOB (if present) in the invoice acceptance hooks for the RPC interface
tests
allow destination TLV pairs to be passed over the RPC payment API