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

Let invoice command specify exact channel(s) to share. #3351

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions common/jsonrpc_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,6 @@
/* Errors from `invoice` command */
#define INVOICE_LABEL_ALREADY_EXISTS 900
#define INVOICE_PREIMAGE_ALREADY_EXISTS 901
#define INVOICE_HINTS_GAVE_NO_ROUTES 902

#endif /* LIGHTNING_COMMON_JSONRPC_ERRORS_H */
13 changes: 9 additions & 4 deletions doc/lightning-invoice.7

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 7 additions & 4 deletions doc/lightning-invoice.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ should not be used unless explicitly needed.
If specified, *exposeprivatechannels* overrides the default route hint
logic, which will use unpublished channels only if there are no
published channels. If *true* unpublished channels are always considered
as a route hint candidate; if *false*, never.
as a route hint candidate; if *false*, never. If it is a short channel id
(e.g. *1x1x3*) or array of short channel ids, only those specific channels
will be considered candidates, even if they are public.

The route hint is selected from the set of incoming channels of which:
peer’s balance minus their reserves is at least *msatoshi*, state is
Expand All @@ -79,13 +81,14 @@ The following error codes may occur:
- -1: Catchall nonspecific error.
- 900: An invoice with the given *label* already exists.
- 901: An invoice with the given *preimage* already exists.
- 902: None of the specified *exposeprivatechannels* were usable.

One of the following warnings may occur (on success):
- *warning\_offline* if no channel with a currently connected peer has
the incoming capacity to pay this invoice
- *warning\_capacity* if there is no channel that has both sufficient
incoming capacity and has a peer that is publicly connected (i.e.
not a dead end)
- *warning\_capacity* if there is no channel that has sufficient
incoming capacity
- *warning\_deadends* if there is no channel that is not a dead-end

AUTHOR
------
Expand Down
9 changes: 6 additions & 3 deletions gossipd/gossip_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,15 @@ msgdata,gossip_dev_compact_store_reply,success,bool,

# master -> gossipd: get route_info for our incoming channels
msgtype,gossip_get_incoming_channels,3025
msgdata,gossip_get_incoming_channels,private_too,?bool,

# gossipd -> master: here they are.
msgtype,gossip_get_incoming_channels_reply,3125
msgdata,gossip_get_incoming_channels_reply,num,u16,
msgdata,gossip_get_incoming_channels_reply,route_info,route_info,num
msgdata,gossip_get_incoming_channels_reply,num_public,u16,
msgdata,gossip_get_incoming_channels_reply,public_route_info,route_info,num_public
msgdata,gossip_get_incoming_channels_reply,public_deadends,bool,num_public
msgdata,gossip_get_incoming_channels_reply,num_private,u16,
msgdata,gossip_get_incoming_channels_reply,private_route_info,route_info,num_private
msgdata,gossip_get_incoming_channels_reply,private_deadends,bool,num_private

# master -> gossipd: blockheight increased.
msgtype,gossip_new_blockheight,3026
Expand Down
45 changes: 14 additions & 31 deletions gossipd/gossipd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1188,18 +1188,6 @@ static bool node_has_public_channels(const struct node *peer,
return false;
}

/*~ The `exposeprivate` flag is a trinary: NULL == dynamic, otherwise
* value decides. Thus, we provide two wrappers for clarity: */
static bool never_expose(bool *exposeprivate)
{
return exposeprivate && !*exposeprivate;
}

static bool always_expose(bool *exposeprivate)
{
return exposeprivate && *exposeprivate;
}

/*~ For routeboost, we offer payers a hint of what incoming channels might
* have capacity for their payment. To do this, lightningd asks for the
* information about all channels to this node; but gossipd doesn't know about
Expand All @@ -1211,14 +1199,12 @@ static struct io_plan *get_incoming_channels(struct io_conn *conn,
struct node *node;
struct route_info *public = tal_arr(tmpctx, struct route_info, 0);
struct route_info *private = tal_arr(tmpctx, struct route_info, 0);
bool has_public;
bool *exposeprivate;
bool *priv_deadends = tal_arr(tmpctx, bool, 0);
bool *pub_deadends = tal_arr(tmpctx, bool, 0);

if (!fromwire_gossip_get_incoming_channels(tmpctx, msg, &exposeprivate))
if (!fromwire_gossip_get_incoming_channels(msg))
master_badmsg(WIRE_GOSSIP_GET_INCOMING_CHANNELS, msg);

has_public = always_expose(exposeprivate);

node = get_node(daemon->rstate, &daemon->rstate->local_id);
if (node) {
struct chan_map_iter i;
Expand All @@ -1227,6 +1213,7 @@ static struct io_plan *get_incoming_channels(struct io_conn *conn,
for (c = first_chan(node, &i); c; c = next_chan(node, &i)) {
const struct half_chan *hc;
struct route_info ri;
bool deadend;

hc = &c->half[half_chan_to(node, c)];

Expand All @@ -1239,25 +1226,21 @@ static struct io_plan *get_incoming_channels(struct io_conn *conn,
ri.fee_proportional_millionths = hc->proportional_fee;
ri.cltv_expiry_delta = hc->delay;

has_public |= is_chan_public(c);

/* If peer doesn't have other public channels,
* no point giving route */
if (!node_has_public_channels(other_node(node, c), c))
continue;

if (always_expose(exposeprivate) || is_chan_public(c))
deadend = !node_has_public_channels(other_node(node, c),
c);
if (is_chan_public(c)) {
tal_arr_expand(&public, ri);
else
tal_arr_expand(&pub_deadends, deadend);
} else {
tal_arr_expand(&private, ri);
tal_arr_expand(&priv_deadends, deadend);
}
}
}

/* If no public channels (even deadend ones!), share private ones. */
if (!has_public && !never_expose(exposeprivate))
msg = towire_gossip_get_incoming_channels_reply(NULL, private);
else
msg = towire_gossip_get_incoming_channels_reply(NULL, public);
msg = towire_gossip_get_incoming_channels_reply(NULL,
public, pub_deadends,
private, priv_deadends);
daemon_conn_send(daemon->master, take(msg));

return daemon_conn_read_next(conn, daemon->master);
Expand Down
Loading