Browse Source

listchannels: allow source arg to list channels by their source node.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
plugin-timeout-inc
Rusty Russell 6 years ago
committed by Christian Decker
parent
commit
dc2ee9639b
  1. 1
      CHANGELOG.md
  2. 7
      contrib/pylightning/lightning/lightning.py
  3. 18
      doc/lightning-listchannels.7
  4. 23
      doc/lightning-listchannels.7.txt
  5. 1
      gossipd/gossip_wire.csv
  6. 12
      gossipd/gossipd.c
  7. 10
      lightningd/gossip_control.c
  8. 9
      tests/test_gossip.py

1
CHANGELOG.md

@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- lightning-cli: `help <cmd>` finds man pages even if `make install` not run. - lightning-cli: `help <cmd>` finds man pages even if `make install` not run.
- JSON API: `waitsendpay` now has an `erring_channel_direction` field. - JSON API: `waitsendpay` now has an `erring_channel_direction` field.
- JSON API: `listpeers` now has a `channel_direction` field in `channels`. - JSON API: `listpeers` now has a `channel_direction` field in `channels`.
- JSON API: `listchannels` now takes a `source` option to filter by node id.
### Changed ### Changed

7
contrib/pylightning/lightning/lightning.py

@ -167,12 +167,13 @@ class LightningRpc(UnixDomainSocketRpc):
} }
return self.call("getroute", payload) return self.call("getroute", payload)
def listchannels(self, short_channel_id=None): def listchannels(self, short_channel_id=None, source=None):
""" """
Show all known channels, accept optional {short_channel_id} Show all known channels, accept optional {short_channel_id} or {source}
""" """
payload = { payload = {
"short_channel_id": short_channel_id "short_channel_id": short_channel_id,
"source": source
} }
return self.call("listchannels", payload) return self.call("listchannels", payload)

18
doc/lightning-listchannels.7

@ -2,12 +2,12 @@
.\" Title: lightning-listchannels .\" Title: lightning-listchannels
.\" Author: [see the "AUTHOR" section] .\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/> .\" Generator: DocBook XSL Stylesheets v1.79.1 <http://docbook.sf.net/>
.\" Date: 01/08/2019 .\" Date: 01/09/2019
.\" Manual: \ \& .\" Manual: \ \&
.\" Source: \ \& .\" Source: \ \&
.\" Language: English .\" Language: English
.\" .\"
.TH "LIGHTNING\-LISTCHANN" "7" "01/08/2019" "\ \&" "\ \&" .TH "LIGHTNING\-LISTCHANN" "7" "01/09/2019" "\ \&" "\ \&"
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
.\" * Define some portability stuff .\" * Define some portability stuff
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
@ -31,14 +31,16 @@
lightning-listchannels \- Command to query active lightning channels in the entire network\&. lightning-listchannels \- Command to query active lightning channels in the entire network\&.
.SH "SYNOPSIS" .SH "SYNOPSIS"
.sp .sp
\fBlistchannels\fR [\fIshort_channel_id\fR] \fBlistchannels\fR [\fIshort_channel_id\fR] [\fIsource\fR]
.SH "DESCRIPTION" .SH "DESCRIPTION"
.sp .sp
The \fBlistchannels\fR RPC command returns data on channels that are known to the node\&. Because channels may be bidirectional, up to 2 objects will be returned for each channel (one for each direction)\&. The \fBlistchannels\fR RPC command returns data on channels that are known to the node\&. Because channels may be bidirectional, up to 2 objects will be returned for each channel (one for each direction)\&.
.sp .sp
If no \fIshort_channel_id\fR is supplied, then data on all lightning channels known to this node, are returned\&. These can be local channels or public channels broadcast on the gossip network\&. If \fIshort_channel_id\fR is supplied, then only known channels with a matching \fIshort_channel_id\fR are returned\&.
.sp .sp
Supplying \fIshort_channel_id\fR will filter the results to only return data for known channels with a matching \fIshort_channel_id\fR\&. If \fIsource\fR is supplied, then only channels leading from that node id are returned\&.
.sp
If neither is supplied, data on all lightning channels known to this node, are returned\&. These can be local channels or public channels broadcast on the gossip network\&.
.SH "RETURN VALUE" .SH "RETURN VALUE"
.sp .sp
On success, an object with a "channels" key is returned containing a list of 0 or more objects\&. On success, an object with a "channels" key is returned containing a list of 0 or more objects\&.
@ -191,7 +193,7 @@ message (BOLT #7)\&.
: The number of blocks delay required to wait for on\-chain settlement when unilaterally closing the channel (BOLT #2)\&. : The number of blocks delay required to wait for on\-chain settlement when unilaterally closing the channel (BOLT #2)\&.
.RE .RE
.sp .sp
If \fIshort_channel_id\fR is supplied and no matching channels are found, a "channels" object with an empty list is returned\&. If \fIshort_channel_id\fR or \fIsource\fR is supplied and no matching channels are found, a "channels" object with an empty list is returned\&.
.SH "ERRORS" .SH "ERRORS"
.sp .sp
If \fIshort_channel_id\fR is not a valid short_channel_id, an error message will be returned: If \fIshort_channel_id\fR is not a valid short_channel_id, an error message will be returned:
@ -206,12 +208,14 @@ If \fIshort_channel_id\fR is not a valid short_channel_id, an error message will
.if n \{\ .if n \{\
.RE .RE
.\} .\}
.sp
Similarly if \fIsource\fR is not a valid pubkey\&.
.SH "AUTHOR" .SH "AUTHOR"
.sp .sp
Michael Hawkins <michael\&.hawkins@protonmail\&.com>\&. Michael Hawkins <michael\&.hawkins@protonmail\&.com>\&.
.SH "SEE ALSO" .SH "SEE ALSO"
.sp .sp
lightning\-fundchannel(7) lightning\-fundchannel(7), lightning\-listnodes(7)
.SH "RESOURCES" .SH "RESOURCES"
.sp .sp
Main web site: https://github\&.com/ElementsProject/lightning Main web site: https://github\&.com/ElementsProject/lightning

23
doc/lightning-listchannels.7.txt

@ -8,7 +8,7 @@ lightning-listchannels - Command to query active lightning channels in the entir
SYNOPSIS SYNOPSIS
-------- --------
*listchannels* ['short_channel_id'] *listchannels* ['short_channel_id'] ['source']
DESCRIPTION DESCRIPTION
----------- -----------
@ -16,12 +16,15 @@ The *listchannels* RPC command returns data on channels that are known to the
node. Because channels may be bidirectional, up to 2 objects will be returned node. Because channels may be bidirectional, up to 2 objects will be returned
for each channel (one for each direction). for each channel (one for each direction).
If no 'short_channel_id' is supplied, then data on all lightning channels known If 'short_channel_id' is supplied, then only known channels with a
to this node, are returned. These can be local channels or public channels matching 'short_channel_id' are returned.
broadcast on the gossip network.
If 'source' is supplied, then only channels leading from that node id
are returned.
Supplying 'short_channel_id' will filter the results to only return data for If neither is supplied, data on all lightning channels known to this
known channels with a matching 'short_channel_id'. node, are returned. These can be local channels or public channels
broadcast on the gossip network.
RETURN VALUE RETURN VALUE
------------ ------------
@ -56,8 +59,8 @@ transferred satoshi (BOLT #2).
- 'delay' : The number of blocks delay required to wait for on-chain settlement - 'delay' : The number of blocks delay required to wait for on-chain settlement
when unilaterally closing the channel (BOLT #2). when unilaterally closing the channel (BOLT #2).
If 'short_channel_id' is supplied and no matching channels are found, a If 'short_channel_id' or 'source' is supplied and no matching channels
"channels" object with an empty list is returned. are found, a "channels" object with an empty list is returned.
ERRORS ERRORS
------ ------
@ -69,13 +72,15 @@ returned:
"message" : "'short_channel_id' should be a short channel id, not '...'" } "message" : "'short_channel_id' should be a short channel id, not '...'" }
---- ----
Similarly if 'source' is not a valid pubkey.
AUTHOR AUTHOR
------ ------
Michael Hawkins <michael.hawkins@protonmail.com>. Michael Hawkins <michael.hawkins@protonmail.com>.
SEE ALSO SEE ALSO
-------- --------
lightning-fundchannel(7) lightning-fundchannel(7), lightning-listnodes(7)
RESOURCES RESOURCES
--------- ---------

1
gossipd/gossip_wire.csv

@ -43,6 +43,7 @@ gossip_getroute_reply,,hops,num_hops*struct route_hop
gossip_getchannels_request,3007 gossip_getchannels_request,3007
gossip_getchannels_request,,short_channel_id,?struct short_channel_id gossip_getchannels_request,,short_channel_id,?struct short_channel_id
gossip_getchannels_request,,source,?struct pubkey
gossip_getchannels_reply,3107 gossip_getchannels_reply,3107
gossip_getchannels_reply,,num_channels,u16 gossip_getchannels_reply,,num_channels,u16

Can't render this file because it has a wrong number of fields in line 6.

12
gossipd/gossipd.c

@ -1971,9 +1971,10 @@ static struct io_plan *getchannels_req(struct io_conn *conn,
struct gossip_getchannels_entry *entries; struct gossip_getchannels_entry *entries;
struct chan *chan; struct chan *chan;
struct short_channel_id *scid; struct short_channel_id *scid;
struct pubkey *source;
/* Note: scid is marked optional in gossip_wire.csv */ /* Note: scid is marked optional in gossip_wire.csv */
if (!fromwire_gossip_getchannels_request(msg, msg, &scid)) if (!fromwire_gossip_getchannels_request(msg, msg, &scid, &source))
master_badmsg(WIRE_GOSSIP_GETCHANNELS_REQUEST, msg); master_badmsg(WIRE_GOSSIP_GETCHANNELS_REQUEST, msg);
entries = tal_arr(tmpctx, struct gossip_getchannels_entry, 0); entries = tal_arr(tmpctx, struct gossip_getchannels_entry, 0);
@ -1982,6 +1983,15 @@ static struct io_plan *getchannels_req(struct io_conn *conn,
chan = get_channel(daemon->rstate, scid); chan = get_channel(daemon->rstate, scid);
if (chan) if (chan)
append_channel(&entries, chan); append_channel(&entries, chan);
} else if (source) {
struct node *s = get_node(daemon->rstate, source);
if (s) {
for (size_t i = 0; i < tal_count(s->chans); i++)
append_half_channel(&entries,
s->chans[i],
!half_chan_to(s,
s->chans[i]));
}
} else { } else {
u64 idx; u64 idx;

10
lightningd/gossip_control.c

@ -453,12 +453,18 @@ static struct command_result *json_listchannels(struct command *cmd,
{ {
u8 *req; u8 *req;
struct short_channel_id *id; struct short_channel_id *id;
struct pubkey *source;
if (!param(cmd, buffer, params, if (!param(cmd, buffer, params,
p_opt("short_channel_id", param_short_channel_id, &id), p_opt("short_channel_id", param_short_channel_id, &id),
p_opt("source", param_pubkey, &source),
NULL)) NULL))
return command_param_failed(); return command_param_failed();
req = towire_gossip_getchannels_request(cmd, id); if (id && source)
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Cannot specify both source and short_channel_id");
req = towire_gossip_getchannels_request(cmd, id, source);
subd_req(cmd->ld->gossip, cmd->ld->gossip, subd_req(cmd->ld->gossip, cmd->ld->gossip,
req, -1, 0, json_listchannels_reply, cmd); req, -1, 0, json_listchannels_reply, cmd);
return command_still_pending(cmd); return command_still_pending(cmd);
@ -467,7 +473,7 @@ static struct command_result *json_listchannels(struct command *cmd,
static const struct json_command listchannels_command = { static const struct json_command listchannels_command = {
"listchannels", "listchannels",
json_listchannels, json_listchannels,
"Show channel {short_channel_id} (or all known channels, if no {short_channel_id})" "Show channel {short_channel_id} or {source} (or all known channels, if not specified)"
}; };
AUTODATA(json_command, &listchannels_command); AUTODATA(json_command, &listchannels_command);

9
tests/test_gossip.py

@ -277,6 +277,15 @@ def test_gossip_jsonrpc(node_factory):
assert len([c for c in channels1 if not c['public']]) == 2 assert len([c for c in channels1 if not c['public']]) == 2
assert len([c for c in channels2 if not c['public']]) == 2 assert len([c for c in channels2 if not c['public']]) == 2
# Test listchannels-by-source
channels1 = l1.rpc.listchannels(source=l1.info['id'])['channels']
channels2 = l2.rpc.listchannels(source=l1.info['id'])['channels']
assert only_one(channels1)['source'] == l1.info['id']
assert only_one(channels1)['destination'] == l2.info['id']
assert channels1 == channels2
channels2 = l2.rpc.listchannels()['channels']
# Now proceed to funding-depth and do a full gossip round # Now proceed to funding-depth and do a full gossip round
l1.bitcoin.generate_block(5) l1.bitcoin.generate_block(5)
# Could happen in either order. # Could happen in either order.

Loading…
Cancel
Save