forked from lightningnetwork/lnd
-
Notifications
You must be signed in to change notification settings - Fork 0
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
Route Blinding Error Handling #9
Open
calvinrzachman
wants to merge
48
commits into
master
Choose a base branch
from
b12-routeblinding-error-handle
base: master
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.
Open
+7,524
−2,400
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 commit introduces the concept of a blinded payment, which consists of a blinded path, aggregate parameters and minimal constraints for the path and basic/sane validation. Payment relay info and payment constraints are placed in the record package, because when the time comes to add support for forwarding of blinded payments, we'll extract these structs as TLVs in our encrypted onion blob. For now, this is not important (it's just an easy way to represent this data), but Aggregate(Relay/Constraints) aliases are used in the routing package to emphasize that these a blinded payment uses aggregate versions of the per-hop struct.
This commit adds the encrypted_data and blinding_point tlvs to the known set of even tlvs for the onion payload. These TLVs are added in two places (the onion payload and hop struct) because lnd uses the same set of TLV types for both structs (and they inherently represent the same thing). Note: in some places, unit tests intentionally mimic the style of older tests, so as to be more consistently readable.
This commit introduces a single struct to hold all of the parameters that are passed to FindRoute. This cleans up an already overloaded function signature and prepares us for handling requests with blinded routes where we need to perform some additional processing on our para (such as extracting the target node from the blinded path).
Add the option to include a blinded route in a route request (exclusive to including hop hints, because it's incongruous to include both), and express the route as a chain of hop hints. Using a chain of hints over a single hint to represent the whole path allows us to re-use our route construction to fill in a lot of the path on our behalf.
When we introduce blinded routes, some of our hops are expected to have zero amounts to forward in their hop payload. This commit updates our hop fee logic to attribute the full blinded route's fees to the introduction node. We can't actually know where/how these fees are distributed, so we collect them all at the introduction node.
With the addition of blinded routes, we now need to account for the possibility that intermediate nodes payloads will not have an amount and expiry set because that information is provided by the recipient encrypted data blob. This commit updates our payload packing to only optionally include those fields.
This commit updates route construction to backfill the fields required for payment to blinded paths and set amount to forward and expiry fields to zero for intermediate hops (as is instructed in the route blinding specification). We could attempt to do this in the first pass, but that loop relies on fields like amount to forward and expiry to calculate each hop backwards, so we keep it simple (stupid) and post processes the blinded portion, since it's computationally cheap and more readable.
Note: This commit can be dropped before merge, it's mostly added to make the PR easier to manually test against other implementations that have bolt 12 invoices implemented already!
We'll need to pack feature vectors for route blinding, so we pull the encoding/decoding out into separate functions (currently contained in ChannelType). Though it's more lines of code, we keep most of the ChannelType assertions so that we strictly enforce use of the alias.
This commit adds encoding and decoding for blinded route data blobs. TLV fields such as path_id (which are only used for the final hop) are omitted to minimize the change size.
Add blinding points to update_add_htlc. This TLV will be set for nodes that are relaying payments in blinded routes that are _not_ the introduction node.
If there is a blinding point present in update_add_htlc's TLVs, add it to our payment descriptor struct so that it can be passed through to onion decryption. This code path will be used for nodes that are relaying payments inside of the blinded route (ie, all nodes except the introduction node). When we restore HTLCs from disk, we do not have the data provided in UpdateAddHTLC's TLVs available. This is okay, because once we store the HTLC as part of our commit state, either have the full wire message stored (for acked but not signed htlcs) or a forwarding package with all forwarding information has been produced (for fully locked in htlcs).
This commit adds a workaround for the fact that we don't have our extra htlc data (ie, that provided in tlvs) stored in channeldb.HTLC. It ensures that we have the blinding point populated on restart for the following set of circumstances: * The incoming HTLC is irrevocably committed to in our local commitment, ie: we have received a CommitSig and sent a RevokeAndAck for a commitment that includes the incoming HTLC. * The incoming HTLC is still pending on the sender, ie: we have not yet sent the remote party a CommitSig covering the incoming HTLC. If we restart at this point, the htlc will be stored as an incoming htlc on our local commitment (with no blinding point) and the full log update will be saved as a LogUpdate in our remote pending updates (because we have not yet provided the remote party with a signature). We restore our remoteUpdateLog from the local commit's incoming htlcs, so before this change these htlcs would be loaded into our in-memory log without their blinding point set (and operation would incorrectly resume as usual without it). This commit updates our logic to restore blinding points (if set) to the htlcs in the remoteUpdateLog.
When we have payments inside of a blinded route, we need to know the incoming amount to be able to back-calculate the amount that we need to forward using the forwarding parameters provided in the blinded route encrypted data. This commit adds the payment amount to our DecodeHopIteratorRequest so that it can be threaded down to payment forwarding information creation in later commits.
Co-authored-by: Calvin Zachman <[email protected]>
Co-authored-by: Calvin Zachman <[email protected]>
This commit introduces a blinding kits which abstracts over the operations required to decrypt, deserialize and reconstruct forwarding data from an encrypted blob of data included for nodes in blinded routes. The concept of a BlindingKey is separated into a separate struct so that it can be used independently of the kit (which is specifically used to process encrypted blobs). This abstraction will be used later to help determine how we handle errors.
When we have a HTLC that is part of a blinded route, we need to include the next ephemeral blinding point in UpdateAddHtlc for the next hop. The way that we handle the addition of this key is the same for introduction nodes and relaying nodes within the route.
If we received a payload with a blinding point set, our forwarding information should be set from the information in our encrypted blob. This behavior is the same for introduction and relying nodes in a blinded route.
Note: the itest is broken up into multiple commits to make it more readable, they can be squashed post-review.
We don't support receiving blinded in this PR - just intercept and settle instead.
Enforce that required fields are present for the last hop in a blind route. Enforce that if an onion has a route blinding payload, then we must receive a blinding point! Also, we properly indicate whether a hop is terminal/final during validation of allowed types.
…with route blinding payload
Verifies that parsing the onion and route blinding TLV payloads yields the expected errors depending on whether the proper fields were included or omitted.
I am not sure this is correct. We do eventually need to allow use of a total_amt_msat field and it seems that MPP record is one way to get that.
- use SendToRouteV2 (as it's not deprecated) - add MPP fields to final hop - create invoice so dave can receive payment to blinded route - ensure alice uses the same preimage/payment hash as invoice in the request to SendToRouteV2
…g local `LogUpdate`
Define an opaque (non-privacy-leaking) error type which is to be used ubiquitously for errors which occur inside a blinded route regardless of the internal or downstream reason for failure.
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.
Change Description
Description of change / link to associated issue.
Steps to Test
Steps for reviewers to follow to test the change.
Pull Request Checklist
Testing
Code Style and Documentation
[skip ci]
in the commit message for small changes.📝 Please see our Contribution Guidelines for further guidance.