jsonrpc: Implemented getchannels JSON-RPC call

This commit is contained in:
Christian Decker 2017-03-22 13:30:09 +01:00 committed by Rusty Russell
parent 60a2227f0d
commit 638594f3c6
5 changed files with 145 additions and 2 deletions

View File

@ -476,6 +476,40 @@ static struct io_plan *getroute_req(struct io_conn *conn, struct daemon *daemon,
return daemon_conn_read_next(conn, &daemon->master);
}
static struct io_plan *getchannels_req(struct io_conn *conn, struct daemon *daemon,
u8 *msg)
{
tal_t *tmpctx = tal_tmpctx(daemon);
u8 *out;
size_t j, num_chans = 0;
struct gossip_getchannels_entry *entries;
struct node *n;
struct node_map_iter i;
entries = tal_arr(tmpctx, struct gossip_getchannels_entry, num_chans);
n = node_map_first(daemon->rstate->nodes, &i);
while (n != NULL) {
for (j=0; j<tal_count(n->out); j++){
tal_resize(&entries, num_chans + 1);
entries[num_chans].source = n->out[j]->src->id;
entries[num_chans].destination = n->out[j]->dst->id;
entries[num_chans].active = n->out[j]->active;
entries[num_chans].delay = n->out[j]->delay;
entries[num_chans].fee_per_kw = n->out[j]->proportional_fee;
entries[num_chans].last_update_timestamp = n->out[j]->last_timestamp;
entries[num_chans].flags = n->out[j]->flags;
entries[num_chans].short_channel_id = n->out[j]->short_channel_id;
num_chans++;
}
n = node_map_next(daemon->rstate->nodes, &i);
}
out = towire_gossip_getchannels_reply(daemon, entries);
daemon_conn_send(&daemon->master, take(out));
tal_free(tmpctx);
return daemon_conn_read_next(conn, &daemon->master);
}
static struct io_plan *getnodes(struct io_conn *conn, struct daemon *daemon)
{
tal_t *tmpctx = tal_tmpctx(daemon);
@ -521,9 +555,13 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
case WIRE_GOSSIP_GETROUTE_REQUEST:
return getroute_req(conn, daemon, daemon->master.msg_in);
case WIRE_GOSSIP_GETCHANNELS_REQUEST:
return getchannels_req(conn, daemon, daemon->master.msg_in);
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
case WIRE_GOSSIP_GETNODES_REPLY:
case WIRE_GOSSIP_GETROUTE_REPLY:
case WIRE_GOSSIP_GETCHANNELS_REPLY:
case WIRE_GOSSIPSTATUS_INIT_FAILED:
case WIRE_GOSSIPSTATUS_BAD_NEW_PEER_REQUEST:
case WIRE_GOSSIPSTATUS_BAD_RELEASE_REQUEST:

View File

@ -71,3 +71,9 @@ gossip_getroute_request,70,riskfactor,u16
gossip_getroute_reply,106
gossip_getroute_reply,0,num_hops,u16
gossip_getroute_reply,2,hops,num_hops*struct route_hop
gossip_getchannels_request,7
gossip_getchannels_reply,107
gossip_getchannels_reply,0,num_channels,u16
gossip_getchannels_reply,2,nodes,num_channels*struct gossip_getchannels_entry

1 # These are fatal.
71
72
73
74
75
76
77
78
79

View File

@ -4,6 +4,7 @@
#include "subd.h"
#include <ccan/err/err.h>
#include <ccan/take/take.h>
#include <ccan/tal/str/str.h>
#include <daemon/jsonrpc.h>
#include <daemon/log.h>
#include <inttypes.h>
@ -143,10 +144,12 @@ static size_t gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
case WIRE_GOSSIPCTL_RELEASE_PEER:
case WIRE_GOSSIP_GETNODES_REQUEST:
case WIRE_GOSSIP_GETROUTE_REQUEST:
case WIRE_GOSSIP_GETCHANNELS_REQUEST:
/* This is a reply, so never gets through to here. */
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
case WIRE_GOSSIP_GETNODES_REPLY:
case WIRE_GOSSIP_GETROUTE_REPLY:
case WIRE_GOSSIP_GETCHANNELS_REPLY:
break;
case WIRE_GOSSIPSTATUS_PEER_BAD_MSG:
peer_bad_message(gossip, msg);
@ -296,3 +299,56 @@ static const struct json_command getroute_command = {
"Returns a {route} array of {id} {msatoshi} {delay}: msatoshi and delay (in blocks) is cumulative."
};
AUTODATA(json_command, &getroute_command);
/* Called upon receiving a getchannels_reply from `gossipd` */
static bool json_getchannels_reply(struct subd *gossip, const u8 *reply,
const int *fds, struct command *cmd)
{
size_t i;
struct gossip_getchannels_entry *entries;
struct json_result *response = new_json_result(cmd);
struct short_channel_id *scid;
if (!fromwire_gossip_getchannels_reply(reply, reply, NULL, &entries)) {
command_fail(cmd, "Invalid reply from gossipd");
return true;
}
json_object_start(response, NULL);
json_array_start(response, "channels");
for (i = 0; i < tal_count(entries); i++) {
scid = &entries[i].short_channel_id;
json_object_start(response, NULL);
json_add_pubkey(response, "source", &entries[i].source);
json_add_pubkey(response, "destination",
&entries[i].destination);
json_add_bool(response, "active", entries[i].active);
json_add_num(response, "fee_per_kw", entries[i].fee_per_kw);
json_add_num(response, "last_update",
entries[i].last_update_timestamp);
json_add_num(response, "flags", entries[i].flags);
json_add_num(response, "delay", entries[i].delay);
json_add_string(response, "short_id",
tal_fmt(reply, "%d:%d:%d/%d", scid->blocknum,
scid->txnum, scid->outnum,
entries[i].flags & 0x1));
json_object_end(response);
}
json_array_end(response);
json_object_end(response);
command_success(cmd, response);
return true;
}
static void json_getchannels(struct command *cmd, const char *buffer,
const jsmntok_t *params)
{
struct lightningd *ld = ld_from_dstate(cmd->dstate);
u8 *req = towire_gossip_getchannels_request(cmd);
subd_req(ld->gossip, req, -1, 0, json_getchannels_reply, cmd);
}
static const struct json_command getchannels_command = {
"getchannels", json_getchannels, "List all known channels.",
"Returns a 'channels' array with all known channels including their fees."};
AUTODATA(json_command, &getchannels_command);

View File

@ -39,3 +39,28 @@ void towire_route_hop(u8 **pptr, const struct route_hop *entry)
towire_u32(pptr, entry->delay);
}
void fromwire_gossip_getchannels_entry(const u8 **pptr, size_t *max,
struct gossip_getchannels_entry *entry)
{
fromwire_short_channel_id(pptr, max, &entry->short_channel_id);
fromwire_pubkey(pptr, max, &entry->source);
fromwire_pubkey(pptr, max, &entry->destination);
entry->active = fromwire_bool(pptr, max);
entry->fee_per_kw = fromwire_u32(pptr, max);
entry->delay = fromwire_u32(pptr, max);
entry->last_update_timestamp = fromwire_u32(pptr, max);
entry->flags = fromwire_u16(pptr, max);
}
void towire_gossip_getchannels_entry(
u8 **pptr, const struct gossip_getchannels_entry *entry)
{
towire_short_channel_id(pptr, &entry->short_channel_id);
towire_pubkey(pptr, &entry->source);
towire_pubkey(pptr, &entry->destination);
towire_bool(pptr, entry->active);
towire_u32(pptr, entry->fee_per_kw);
towire_u32(pptr, entry->delay);
towire_u32(pptr, entry->last_update_timestamp);
towire_u16(pptr, entry->flags);
}

View File

@ -10,10 +10,28 @@ struct gossip_getnodes_entry {
u16 port;
};
void fromwire_gossip_getnodes_entry(const tal_t *ctx, const u8 **pptr, size_t *max, struct gossip_getnodes_entry *entry);
void towire_gossip_getnodes_entry(u8 **pptr, const struct gossip_getnodes_entry *entry);
struct gossip_getchannels_entry {
struct pubkey source, destination;
u32 fee_per_kw;
bool active;
struct short_channel_id short_channel_id;
u32 last_update_timestamp;
u32 delay;
u16 flags;
};
void fromwire_gossip_getnodes_entry(const tal_t *ctx, const u8 **pptr,
size_t *max,
struct gossip_getnodes_entry *entry);
void towire_gossip_getnodes_entry(u8 **pptr,
const struct gossip_getnodes_entry *entry);
void fromwire_route_hop(const u8 **pprt, size_t *max, struct route_hop *entry);
void towire_route_hop(u8 **pprt, const struct route_hop *entry);
void fromwire_gossip_getchannels_entry(const u8 **pptr, size_t *max,
struct gossip_getchannels_entry *entry);
void towire_gossip_getchannels_entry(
u8 **pptr, const struct gossip_getchannels_entry *entry);
#endif /* LIGHTNING_LIGHTGNINGD_GOSSIP_MSG_H */