Skip to content
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

[feature]: Payment to BOLT 12 Invoices (with Blinded Paths) #7201

Open
carlaKC opened this issue Nov 23, 2022 · 0 comments
Open

[feature]: Payment to BOLT 12 Invoices (with Blinded Paths) #7201

carlaKC opened this issue Nov 23, 2022 · 0 comments
Labels
blinded paths bolt12 enhancement Improvements to existing features / behaviour

Comments

@carlaKC
Copy link
Collaborator

carlaKC commented Nov 23, 2022

This issue outlines a proposal for adding support for payment to blinded routes in BOLT12 invoices. It depends on #7200, which outline pathfinding strategy. This issue will focus on integrating this new type of format in our existing payment flow. This issue does not outline parsing of a BOLT 12 invoice itself, since it's just a TLV stream.

Parent: #5594

Background

Payments to blinded routes allow for better receiver-side privacy in the Lightning Network. Rather than providing its public key in invoices, recipient nodes can generate blinded routes to themselves and encrypted data blobs for each hop in the blinded route to extract its forwarding information from.

Payment State Machine Updates

API Updates

A BOLT12 invoice string can be passed via LND’s existing SendPayment APIs, using a single (marked experimental) field. This allows easy isolation of the change, and does not add significant overhead if LND chooses to overhaul its APIs at a later date.

Payment Creation

When LND creates a payment, it stores payment information with the control tower. This information includes a bolt 11 encoded payment request which is stored as a length and var bytes on disk. This field is currently only used to surface information on the rpc, but not used in any meaningful capacity.

There are three paths to adding a new field to this record:

  • Quick ‘n Dirty: Just add a length / var bytes bolt 12 invoice after our bolt 11 payment request on disk, we can detect its presence by attempting to read the remaining bytes and catching an EOF error if there isn’t anything else in the record.
  • Migration: Migrate payment control information to be stored as a TLV stream, which will be easily extensible in future. This has the downside of requiring a migration in a critical part of the codebase, never fun.
  • Reuse payment request: Store a bolt 12 invoice in the existing payment request field, then logically interpret the value on higher layers. While we don’t actually use this field now, I suspect this will get messy if we ever end up needing these values.

Since we’re unlikely to add another format of payment request (god help us all, please no), I’d suggest that it’s worthwhile taking the quick ‘n dirty approach and just add the field on to payment control.

Payment Dispatch

Payment dispatch is unchanged for payments to blinded routes. Construction of a route with relevant additional information is covered in #7200, so payments just need to thread through blinded route hop hints to request route and dispatch as usual.

Payment Resume

When we resume in-flight payments on restart, we do not attempt to re-launch any shards. This makes resuming payments to blinded routes identical to others - start up, wait for shard resolution, record results.

If we do extend lnd to re-launch shards after restart, we should be able to do so with the information stored by the control tower (in the same way we’d do for legacy payments that need hop hints to succeed).

Error Handling and Mission Control

The errors returned by nodes in blinded routes are less informative than regular routing errors to prevent probing. The latest (at time of writing) route blinding proposal instructs introduction nodes to convert any error into a malformed onion with an invalid_onion_blinding code. This will make it appear that all errors originated from the introduction node, even if the failure actually occurred elsewhere in the blinded route.

There are two key differences between blinded routes and hop hints that affect the way we handle them in mission control:

  • Single-use: we can reasonably expect the node ids in blinded routes to be single-use, as they are generated with a blinded route. This means that mission control results for a blinded route will only be used within the scope of one payment attempt.
  • “All in it together”: The incentives for nodes in blinded routes to lie about routing results is different, because the sender needs to use the entire route, or none of it at all (poisoning your blinded route neighbors poisons yourself)

For blinded paths, we need to be cautious around reporting. We don’t want to blame introduction nodes for routing failures in the blinded path, because we could end up writing off a good public routing node. We pass the full route to mission control, including hops that allow us to identify the introduction node by the presence of a blinding point.

Proposed error handling for invalid_onion_blinding:

  • Received from introduction node: penalize all nodes after the introduction node, effectively punishing the full blinded route. We do not penalize the introduction node itself to avoid hammering popular nodes for the sins of their blinded peers.
  • Received from node outside of the blinded route: permanently penalize the node, it is either borked or attempting to sabotage the nodes around it.
@carlaKC carlaKC added the enhancement Improvements to existing features / behaviour label Nov 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blinded paths bolt12 enhancement Improvements to existing features / behaviour
Projects
None yet
Development

No branches or pull requests

2 participants