Browse Source

JSONRPC: getnodes: rename to listnodes.

Like listinvoice, and add optional 'id' parameter to ask about a
specific node.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
parent
commit
ced572b973
  1. 41
      gossipd/gossip.c
  2. 3
      gossipd/gossip_wire.csv
  3. 30
      lightningd/gossip_control.c
  4. 12
      tests/test_lightningd.py

41
gossipd/gossip.c

@ -1095,23 +1095,40 @@ static struct io_plan *getchannels_req(struct io_conn *conn, struct daemon *daem
return daemon_conn_read_next(conn, &daemon->master); return daemon_conn_read_next(conn, &daemon->master);
} }
static struct io_plan *getnodes(struct io_conn *conn, struct daemon *daemon) static void append_node(struct gossip_getnodes_entry **nodes,
const struct node *n)
{
size_t num_nodes = tal_count(*nodes);
tal_resize(nodes, num_nodes + 1);
(*nodes)[num_nodes].nodeid = n->id;
(*nodes)[num_nodes].addresses = n->addresses;
}
static struct io_plan *getnodes(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{ {
tal_t *tmpctx = tal_tmpctx(daemon); tal_t *tmpctx = tal_tmpctx(daemon);
u8 *out; u8 *out;
struct node *n; struct node *n;
struct node_map_iter i;
struct gossip_getnodes_entry *nodes; struct gossip_getnodes_entry *nodes;
size_t node_count = 0; struct pubkey *ids;
nodes = tal_arr(tmpctx, struct gossip_getnodes_entry, node_count); fromwire_gossip_getnodes_request(tmpctx, msg, NULL, &ids);
n = node_map_first(daemon->rstate->nodes, &i);
while (n != NULL) { nodes = tal_arr(tmpctx, struct gossip_getnodes_entry, 0);
tal_resize(&nodes, node_count + 1); if (ids) {
nodes[node_count].nodeid = n->id; for (size_t i = 0; i < tal_count(ids); i++) {
nodes[node_count].addresses = n->addresses; n = node_map_get(daemon->rstate->nodes, &ids[i].pubkey);
node_count++; if (n)
n = node_map_next(daemon->rstate->nodes, &i); append_node(&nodes, n);
}
} else {
struct node_map_iter i;
n = node_map_first(daemon->rstate->nodes, &i);
while (n != NULL) {
append_node(&nodes, n);
n = node_map_next(daemon->rstate->nodes, &i);
}
} }
out = towire_gossip_getnodes_reply(daemon, nodes); out = towire_gossip_getnodes_reply(daemon, nodes);
daemon_conn_send(&daemon->master, take(out)); daemon_conn_send(&daemon->master, take(out));
@ -1749,7 +1766,7 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
return release_peer(conn, daemon, master->msg_in); return release_peer(conn, daemon, master->msg_in);
case WIRE_GOSSIP_GETNODES_REQUEST: case WIRE_GOSSIP_GETNODES_REQUEST:
return getnodes(conn, daemon); return getnodes(conn, daemon, daemon->master.msg_in);
case WIRE_GOSSIP_GETROUTE_REQUEST: case WIRE_GOSSIP_GETROUTE_REQUEST:
return getroute_req(conn, daemon, daemon->master.msg_in); return getroute_req(conn, daemon, daemon->master.msg_in);

3
gossipd/gossip_wire.csv

@ -83,6 +83,9 @@ gossipctl_hand_back_peer,,msg,len*u8
# Pass JSON-RPC getnodes call through # Pass JSON-RPC getnodes call through
gossip_getnodes_request,3005 gossip_getnodes_request,3005
# Can be 0 or 1 currently
gossip_getnodes_request,,num,u16
gossip_getnodes_request,,id,num*struct pubkey
#include <lightningd/gossip_msg.h> #include <lightningd/gossip_msg.h>
gossip_getnodes_reply,3105 gossip_getnodes_reply,3105

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

30
lightningd/gossip_control.c

@ -211,18 +211,38 @@ static void json_getnodes_reply(struct subd *gossip, const u8 *reply,
command_success(cmd, response); command_success(cmd, response);
} }
static void json_getnodes(struct command *cmd, const char *buffer, static void json_listnodes(struct command *cmd, const char *buffer,
const jsmntok_t *params) const jsmntok_t *params)
{ {
u8 *req = towire_gossip_getnodes_request(cmd); u8 *req;
jsmntok_t *idtok = NULL;
struct pubkey *id = NULL;
if (!json_get_params(buffer, params,
"?id", &idtok,
NULL)) {
command_fail(cmd, "Invalid arguments");
return;
}
if (idtok) {
id = tal_arr(cmd, struct pubkey, 1);
if (!json_tok_pubkey(buffer, idtok, id)) {
command_fail(cmd, "Invalid id");
return;
}
}
req = towire_gossip_getnodes_request(cmd, id);
subd_req(cmd, cmd->ld->gossip, req, -1, 0, json_getnodes_reply, cmd); subd_req(cmd, cmd->ld->gossip, req, -1, 0, json_getnodes_reply, cmd);
command_still_pending(cmd); command_still_pending(cmd);
} }
static const struct json_command getnodes_command = { static const struct json_command listnodes_command = {
"getnodes", json_getnodes, "Retrieve all nodes in our local network view", "listnodes", json_listnodes,
"List a nodes in our local network view (or all, if no {id})",
"Returns a list of all nodes that we know about"}; "Returns a list of all nodes that we know about"};
AUTODATA(json_command, &getnodes_command); AUTODATA(json_command, &listnodes_command);
static void json_getroute_reply(struct subd *gossip, const u8 *reply, const int *fds, static void json_getroute_reply(struct subd *gossip, const u8 *reply, const int *fds,
struct command *cmd) struct command *cmd)

12
tests/test_lightningd.py

@ -1412,9 +1412,15 @@ class LightningDTests(BaseLightningDTests):
'Channel {}\\(1\\) was updated.' 'Channel {}\\(1\\) was updated.'
.format(channel_id)]) .format(channel_id)])
nodes = l1.rpc.getnodes()['nodes'] nodes = l1.rpc.listnodes()['nodes']
assert set([n['nodeid'] for n in nodes]) == set([l1.info['id'], l2.info['id']]) assert set([n['nodeid'] for n in nodes]) == set([l1.info['id'], l2.info['id']])
# Test listnodes with an arg, while we're here.
n1 = l1.rpc.listnodes(l1.info['id'])['nodes'][0]
n2 = l1.rpc.listnodes(l2.info['id'])['nodes'][0]
assert n1['nodeid'] == l1.info['id']
assert n2['nodeid'] == l2.info['id']
assert [c['active'] for c in l1.rpc.getchannels()['channels']] == [True, True] assert [c['active'] for c in l1.rpc.getchannels()['channels']] == [True, True]
assert [c['public'] for c in l1.rpc.getchannels()['channels']] == [True, True] assert [c['public'] for c in l1.rpc.getchannels()['channels']] == [True, True]
assert [c['active'] for c in l2.rpc.getchannels()['channels']] == [True, True] assert [c['active'] for c in l2.rpc.getchannels()['channels']] == [True, True]
@ -1470,8 +1476,8 @@ class LightningDTests(BaseLightningDTests):
assert scid2 not in [c['short_channel_id'] for c in l1.rpc.getchannels()['channels']] assert scid2 not in [c['short_channel_id'] for c in l1.rpc.getchannels()['channels']]
assert scid2 not in [c['short_channel_id'] for c in l2.rpc.getchannels()['channels']] assert scid2 not in [c['short_channel_id'] for c in l2.rpc.getchannels()['channels']]
assert l3.info['id'] not in [n['nodeid'] for n in l1.rpc.getnodes()['nodes']] assert l3.info['id'] not in [n['nodeid'] for n in l1.rpc.listnodes()['nodes']]
assert l3.info['id'] not in [n['nodeid'] for n in l2.rpc.getnodes()['nodes']] assert l3.info['id'] not in [n['nodeid'] for n in l2.rpc.listnodes()['nodes']]
def ping_tests(self, l1, l2): def ping_tests(self, l1, l2):
# 0-byte pong gives just type + length field. # 0-byte pong gives just type + length field.

Loading…
Cancel
Save