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

invoicesrpc: specify private hops for addinvoice, addholdinvoice #3022

Closed

Conversation

Crypt-iQ
Copy link
Collaborator

@Crypt-iQ Crypt-iQ commented Apr 28, 2019

Fixes #2963

This PR allows a user to manually specify private channels to be used as hop hints in both the addinvoice and addholdinvoice RPC calls via the new --private_hops flag which accepts a JSON array of private channel ids. The new flag must be used in conjunction with the --private flag. In the current implementation, users will advertise all private channels which isn't ideal for privacy-conscious users.

I also changed the --private flag from BoolTFlag to BoolFlag so that users aren't always leaking their private channels if they don't want to.

Usage:

  • addinvoice
    lncli addinvoice --private_hops '[467292441870336, 447501232570368, 487083651170304]' --private

  • addholdinvoice
    lncli addholdinvoice <hash> --private_hops '[467292441870336, 447501232570368, 487083651170304]' --private

@Roasbeef Roasbeef added P3 might get fixed, nice to have routing rpc Related to the RPC interface labels Jun 18, 2019
@Roasbeef Roasbeef requested a review from joostjager July 2, 2019 02:05
Copy link
Contributor

@joostjager joostjager left a comment

Choose a reason for hiding this comment

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

In terms of commit structure, it may be better to just make two commits: one for lnd and one for lncli building off of that.

cli.StringFlag{
Name: "private_hops",
Usage: "a json array string of private channel ids " +
"to use as hop hints",
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not the simpler format --private_hops 100,200,300?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

Name: "private_hops",
Usage: "a json array string of private channel ids " +
"to use as hop hints",
},
Copy link
Contributor

Choose a reason for hiding this comment

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

If you want, you can do some reuse here. See commands.go, paymentFlags().

lnrpc/invoicesrpc/addinvoice.go Outdated Show resolved Hide resolved
// any channels not in the array.
if len(invoice.PrivateHops) > 0 {
match := false
for _, privateChan := range invoice.PrivateHops {
Copy link
Contributor

Choose a reason for hiding this comment

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

This may be better to implement using a map[uint64]struct{}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Agree, done

/**
The list of private channel ids that will be used as hop hints.
*/
repeated uint64 private_hops = 10 [json_name = "private_hops"];
Copy link
Contributor

Choose a reason for hiding this comment

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

Wondering whether name should be private_channels? But we also have hop hints...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Changed to private_channels since I think it's more descriptive

@joostjager
Copy link
Contributor

Can you also give a bit more background on how exactly you'd be using this? Is the goal to only expose one private channel for every peer connected to, so that the invoice doesn't disclose the combined capacity of all channels to a peer?

Or do you maybe have info on how the sender is going to approach you?

@Crypt-iQ
Copy link
Collaborator Author

Crypt-iQ commented Jul 2, 2019

Currently the commands include all private channels as hop hints by default. Users may not even know that this is happening (I didn't), so I disabled that in this PR. If I only wanted to specify one, or a few, for the sender to use in path finding, this gives me more granular control. Perhaps some of these private channels are unbalanced and could use some balancing. Maybe there is one "very secret" private channel that I don't want exposed via the regular add(hold)invoice command(s) and I don't really care if my other private channels get exposed to the sender.

@andronoob
Copy link

andronoob commented Aug 9, 2019

@joostjager I'm looking for this feature as well. My Internet connection comes with carrier-grade NAT, so simply setting NAT=true didn't seem to work. I have to embed routing hints of the channel counterparty to receive funds. Eclair mobile has done this properly, while LN-App still generates invoices without any routing hints, which cannot be paid.
I think maybe I should open private channels instead of public channels? In my opinion, there should be some protocol layer workaround, which could work like ssh -R 0.0.0.0:9735:127.0.0.1:9735

@halseth
Copy link
Contributor

halseth commented Sep 18, 2019

@andronoob Yes, for non-routing nodes you should be using private channels.

@andronoob
Copy link

@halseth In other words, it's a limitation of LN protocol that NAT can be a problem for routing nodes, therefore routing nodes must figure out how to overcome this problem by themselves, right?

@halseth
Copy link
Contributor

halseth commented Sep 23, 2019

A routing node must be connectable, and how that is achieved is not a protocol problem.

therefore routing nodes must figure out how to overcome this problem by themselves, right?

So yes :)

@Crypt-iQ Crypt-iQ force-pushed the private_invoice_0427 branch from 861cc07 to c40e926 Compare November 7, 2019 15:59
Copy link
Collaborator

@carlaKC carlaKC left a comment

Choose a reason for hiding this comment

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

Nice addition, thanks @Crypt-iQ!
Just a few nits/ UX questions from my side :)

@@ -82,6 +82,11 @@ message AddHoldInvoiceRequest {

/// Whether this invoice should include routing hints for private channels.
bool private = 9 [json_name = "private"];

/**
The list of private channel ids that will be used as hop hints.
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: add that these are short channel IDs?
It's apparent from the uint64 when you're used to the rpc, but might be helpful for newer users :)

@@ -6,6 +6,7 @@ import (
"context"
"encoding/hex"
"fmt"
"strings"

Copy link
Collaborator

Choose a reason for hiding this comment

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

Might as well blitz this unnecessary newline while you're here?

@@ -253,6 +258,16 @@ func AddInvoice(ctx context.Context, cfg *AddInvoiceConfig,
options = append(options, zpay32.CLTVExpiry(uint64(defaultDelta)))
}

if len(invoice.PrivateChannels) > 0 && !invoice.Private {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Wouldn't the presence of a list of private channels imply that the user wants to have a private invoice?
Non-critical, but I can definitely see myself calling with a list of channels and forgetting the private flag and wanting it to be set anyway.

// the list of hop hints.
sid := channel.ShortChannelID.ToUint64()
if _, ok := privateChanMap[sid]; !ok {
continue
Copy link
Collaborator

Choose a reason for hiding this comment

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

As is, users can provide public or already closed channels in this list and they will just be filtered out by this + the isPublic check, which could result in there being no hints added when the user gives bad input?

The extreme case would be to error if they provide hops and we end up using none, but maybe just add some logging along the lines of private invoice: received {len} suggested channels, created: {numHints} hints?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Gotcha, agree

@@ -2242,6 +2242,11 @@ message Invoice {

/// List of HTLCs paying to this invoice [EXPERIMENTAL].
repeated InvoiceHTLC htlcs = 22 [json_name = "htlcs"];

/**
The list of private channel ids that will be used as hop hints.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Add a comment that hop hints will be strictly limited to these channels if they are specified?

@alexbosworth
Copy link
Contributor

A potential workaround for this issue now exists with the signMessage RPC API, you can encode your own BOLT 11 payment request however you like and then use that API to craft the signature for the payment request

@Crypt-iQ
Copy link
Collaborator Author

A potential workaround for this issue now exists with the signMessage RPC API, you can encode your own BOLT 11 payment request however you like and then use that API to craft the signature for the payment request

I agree with this, but I think that might be complicated for new users? Also at a minimum I think the private hops should not be specified by default if possible

@Roasbeef Roasbeef added this to the 0.10.0 milestone Jan 14, 2020
@Roasbeef Roasbeef added the v0.10 label Jan 17, 2020
@Roasbeef Roasbeef removed this from the 0.10.0 milestone Feb 18, 2020
@Roasbeef Roasbeef removed the v0.10 label Feb 26, 2020
@halseth
Copy link
Contributor

halseth commented Sep 11, 2020

@Crypt-iQ Can we close in favor of #3672?

@Crypt-iQ Crypt-iQ closed this Sep 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P3 might get fixed, nice to have routing rpc Related to the RPC interface
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Specify individual private channels in addinvoice call
7 participants