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

routing: Support Pathfinding to Blinded Routes #7267

Merged

Conversation

carlaKC
Copy link
Collaborator

@carlaKC carlaKC commented Dec 20, 2022

Change Description

This PR surfaces the ability to create routes to blinded path via the QueryRoutes api. It takes the approach of expressing a blinded path as a chain of hop hints, and backfills all the fields required for blinded payments in a second pass.

Fixes #7200.
Depends on lightning-onion/57.

Steps to Test - LDK

Setup the following network + channels using my branch of ldk-sample: LND --- LDK0 --- LDK1

Create an invoice on LDK1:

  • getinvoice (amt) (expiry seconds) -> lnr...
  • lncli decodepayreq lnr... -> get payment hash, payment addr and cltv delta

Create a blinded path to LDK1 using tests:

  • Checkout my branch of rust-lightning and open lightning/src/blinded_path/test.rs
  • Update the following variables:
    • introduction_node = LDK0 pubkey
    • blinded_node = LDK1 pubkey
    • payment_secret = payment addr from invoice
    • channel_id = channel connecting LDK0 --> LDK1
  • Run the test using cargo test -- --nocapture test_blinded_path -> this will print out a blinded path.

Pay the blinded path via LND:

lncli queryroutes 
--introduction_point={cleartext_introduction_node_id} 
--blinding_point={blinding_point} 
--blinded_hops={blinded_introduction_node}:{introduction_node_data}
--blinded_hops={blinded_node}:{blinded_node_data}
--blinded_cltv= 120 + {invoice_cltv_delta}
--amt={invoice_amount} |
 lncli sendtoroute --payment_hash={payment_hash} -

The payment should succeed!

Footguns:

  • CLTV: make sure to add the delta in the LDK invoice to the value provided in the blinded path (which is just hardcoded to 120).
  • Payment address: needs to be unique per-payment (for LDK reasons), so you have to regenerate every time.

Steps to Test - CLN

(this way is harder IMO, but was originally included in the PR description). Since LND doesn't _produce_ blinded routes or forward blinded payments, you'll need the following setup: `Alice (LND) --- Bob(CLN) --- Carol (CLN) --privatechan-- Dave(CL)`

Run all CLN nodes in developer mode with: --experimental-offers --dev-fast-gossip.

You want an invoice with a blinded path, to do this you can create an offer and then fetch the raw invoice:

  • cl-dave offer 1000 test -> lno... is your offer
  • cl-carol fetchinvoice lno... -> lni.... is your invoice
  • cl-carol decode lni... -> This will give blinded hops/data etc.

You can then pay the blinded invoice from LND:

lncli queryroutes --introduction_point={cleartext_introduction_node_id} --blinding_point={blinding_point} --blinded_hops={blinded_introduction_node}:{introduction_node_data} --blinded_cltv={blinded_route_total_cltv} --amt={invoice_amount} | lncli sendtoroute --payment_hash={payment_hash} -

CLN only creates a blinded path when the node has private channels, and otherwise will just create an invoice with the receiving node as the introduction node. To test different variations of blinded paths:

  • With blinded hop: create offer on Dave and fetch with Carol
  • With just introduction hop: create offer on Carol and fetch with Bob

@carlaKC
Copy link
Collaborator Author

carlaKC commented Dec 20, 2022

Opening this PR early to get feedback on the approach 🙏 As we open up more PRs for route blinding, this should be easier to test and form a more coherent piece of work.

@Roasbeef Roasbeef added onion routing crypto Related to the cryptography underlying LND path finding blinded paths labels Dec 20, 2022
@carlaKC carlaKC force-pushed the 7200-blindedpathfinding branch 2 times, most recently from f54d2ff to 15b1caf Compare December 21, 2022 19:39
@carlaKC carlaKC force-pushed the 7200-blindedpathfinding branch from 15b1caf to 33a91e0 Compare December 30, 2022 17:12
@carlaKC carlaKC force-pushed the 7200-blindedpathfinding branch 2 times, most recently from a2ea2d1 to cadb3a7 Compare January 20, 2023 15:28
@carlaKC carlaKC force-pushed the 7200-blindedpathfinding branch 3 times, most recently from ae34076 to 6b3bbf3 Compare January 27, 2023 22:37
@yyforyongyu yyforyongyu self-requested a review January 30, 2023 08:55
@carlaKC carlaKC force-pushed the 7200-blindedpathfinding branch from 6b3bbf3 to 47029e2 Compare January 31, 2023 22:46
Copy link
Contributor

@bjarnemagnussen bjarnemagnussen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just leaving some smaller comments for things I fell over while taking a glimpse at it.

cmd/lncli/cmd_payments.go Outdated Show resolved Hide resolved
routing/blinding.go Outdated Show resolved Hide resolved
routing/router.go Outdated Show resolved Hide resolved
routing/pathfind.go Show resolved Hide resolved
lnrpc/lightning.proto Outdated Show resolved Hide resolved
lnrpc/routerrpc/router_backend.go Outdated Show resolved Hide resolved
@carlaKC carlaKC force-pushed the 7200-blindedpathfinding branch from 47029e2 to 67bfc14 Compare February 6, 2023 17:22
@saubyk saubyk added this to the v0.17.0 milestone Apr 7, 2023
@saubyk saubyk requested a review from bitromortac April 12, 2023 17:18
@saubyk saubyk assigned carlaKC and unassigned bitromortac Apr 14, 2023
Copy link
Collaborator

@bitromortac bitromortac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very good on first pass 🚀, great work on introducing all the essential onion building blocks for blinded routes!
I think that there may be some overlap with #6920 (this is @joostjager's idea to unify route construction by letting pathfinding do all the work and to remove newRoute, potentially it would be worth it to land this first) and #6934 (inbound fee sending support).

record/blinded_data.go Outdated Show resolved Hide resolved
routing/blinding.go Outdated Show resolved Hide resolved
routing/blinding_test.go Outdated Show resolved Hide resolved
record/hop.go Show resolved Hide resolved
routing/route/route.go Show resolved Hide resolved
lntest/itest/lnd_route_blinding.go Outdated Show resolved Hide resolved
lntest/itest/lnd_route_blinding.go Outdated Show resolved Hide resolved
lntest/itest/lnd_route_blinding.go Outdated Show resolved Hide resolved
lntest/itest/lnd_route_blinding.go Outdated Show resolved Hide resolved
lnrpc/lightning.proto Outdated Show resolved Hide resolved
@carlaKC carlaKC force-pushed the 7200-blindedpathfinding branch from 67bfc14 to 15587e6 Compare May 25, 2023 21:20
@carlaKC
Copy link
Collaborator Author

carlaKC commented May 25, 2023

Thanks for taking a look! Rebased on master, addressed comments and updated to the latest and greatest lightning-onion version.

think that there may be some overlap with #6920 (this is @joostjager's idea to unify route construction by letting pathfinding do all the work and to remove newRoute

I'm reticent to make this a dependency of the refactor (since the forwarding PR already depends on this), but I'll keep track of it + rebase as required!

Copy link
Collaborator

@ziggie1984 ziggie1984 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work Carla, feels close to have Route-Blinding in LND :) 🚀

record/blinded_data.go Outdated Show resolved Hide resolved
routing/route/route_test.go Outdated Show resolved Hide resolved
routing/blinding.go Outdated Show resolved Hide resolved
routing/route/route_test.go Outdated Show resolved Hide resolved
routing/pathfind_test.go Show resolved Hide resolved
lnrpc/lightning.proto Outdated Show resolved Hide resolved
lnrpc/lightning.proto Show resolved Hide resolved
lnrpc/routerrpc/router_backend.go Outdated Show resolved Hide resolved
itest/lnd_route_blinding.go Show resolved Hide resolved
itest/lnd_route_blinding.go Outdated Show resolved Hide resolved
@carlaKC carlaKC force-pushed the 7200-blindedpathfinding branch from 15587e6 to 8a6e7cd Compare May 31, 2023 21:55
@carlaKC
Copy link
Collaborator Author

carlaKC commented Sep 5, 2023

Please give me a shout when this needs a rebase!
Seems unnecessarily noisy to rebase on docs/protos so I'm going to leave as-is for now.

@yyforyongyu
Copy link
Member

let's rebase and merge? cc @guggero

@carlaKC carlaKC force-pushed the 7200-blindedpathfinding branch from 44edf4b to 1040cb6 Compare September 13, 2023 13:54
@lightninglabs-deploy
Copy link

@ellemouton: review reminder
@bitromortac: review reminder
@carlaKC, remember to re-request review from reviewers when ready

This commit adds a representation of blinded payments, which include a
blinded path and aggregate routing parameters to be used in payment to
the path.
This commit adds the encrypted_data, blinding_point and total_amt_msat
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.
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.
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.
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.
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.
Blinded routes can now have "hints" that have zero value edges, so we
remove this log to avoid spamming logs.
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!
@carlaKC carlaKC force-pushed the 7200-blindedpathfinding branch from 1040cb6 to e334fc0 Compare September 27, 2023 19:22
@yyforyongyu yyforyongyu merged commit bccd218 into lightningnetwork:0-18-staging Sep 28, 2023
25 checks passed
@bitromortac
Copy link
Collaborator

Sorry about that late question. If a blinded payment fails within the blinded portion of the route, the error will be converted to a normal error by the introduction node if I understand correctly, which means that they will be seen as the node to blame. I think that this could lead to a decreased incentive for routers to support route blinding. Perhaps instead we would like to only penalize a node pair within the blinded route such that we keep the node probability of the introduction node untouched, which would avoid to send to the same blinded route again as well. I could open an issue for follow-up discussions if my assumptions are correct.

@carlaKC
Copy link
Collaborator Author

carlaKC commented Sep 28, 2023

the error will be converted to a normal error by the introduction node if I understand correctly, which means that they will be seen as the node to blame. I think that this could lead to a decreased incentive for routers to support route blinding.

Yeah def! I owe ya'll a quick mission control follow up for this PR (discussed somewhere in here but I've lost it in the comments). Been thinking about this more and I think that it makes sense to penalize every node after the introduction node:

  • Intro node has no incentive to "fake blame" everyone else because they are not permanently affected (since they're blinded), and the intro getting paid depends on the blinded route.
  • That will have the effect of discounting the blinded path (which starts to matter when we have multiple blinded paths) as you note!

Update: totally forgot I made an issue for this: #7882

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blinded paths crypto Related to the cryptography underlying LND onion routing path finding
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[feature]: Pathfinding To Blinded Routes
9 participants