Skip to content

Commit

Permalink
WIP: topology listchannels: apply private channel data
Browse files Browse the repository at this point in the history
  • Loading branch information
endothermicdev committed Sep 19, 2023
1 parent 862435f commit 2818316
Showing 1 changed file with 93 additions and 6 deletions.
99 changes: 93 additions & 6 deletions plugins/topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,43 @@ static struct command_result *json_getroute(struct command *cmd,
return command_finished(cmd, js);
}

struct channel_routing_data {
struct amount_msat fee_base;
struct amount_msat fee_ppm;
u16 delay;
struct amount_msat htlc_minimum_msat;
struct amount_msat htlc_maximum_msat;
};

struct private_channel {
struct short_channel_id scid;
struct node_id nodes[2];
struct channel_routing_data half_chan_data[2];
struct amount_msat amount_msat;
/* FIXME: Add full data to populate listchannels */
};
/* FIXME: Add private_channel_populate_from_result */

static inline const struct short_channel_id *priv_chan_scid(const struct private_channel *c)
{
return &c->scid;
}

static inline size_t hash_scid(const struct short_channel_id *scid)
{
/* scids cost money to generate, so simple hash works here */
return (scid->u64 >> 32) ^ (scid->u64 >> 16) ^ scid->u64;
}

static inline bool chan_eq_scid(const struct private_channel *c,
const struct short_channel_id *scid)
{
return short_channel_id_eq(scid, &c->scid);
}

HTABLE_DEFINE_TYPE(struct private_channel, priv_chan_scid, hash_scid, chan_eq_scid,
private_channel_map);

HTABLE_DEFINE_TYPE(struct node_id, node_id_keyof, node_id_hash, node_id_eq,
node_map);

Expand Down Expand Up @@ -287,18 +324,26 @@ struct listchannels_opts {
* channels in the store it knows nothing about. */
static struct node_map *local_connected(const tal_t *ctx,
const char *buf,
const jsmntok_t *result)
const jsmntok_t *result,
const jsmntok_t *inbound_result,
struct private_channel_map **private)
{
size_t i;
const jsmntok_t *channel, *channels = json_get_member(buf, result, "channels");
struct node_map *connected = tal(ctx, struct node_map);

node_map_init(connected);
tal_add_destructor(connected, node_map_clear);
*private = tal(ctx, struct private_channel_map);
private_channel_map_init(*private);
tal_add_destructor(*private, private_channel_map_clear);

json_for_each_arr(i, channel, channels) {
struct node_id id;
bool is_connected;
const jsmntok_t *private_tok, *scid_tok;
bool is_private;
struct short_channel_id scid;
const char *err, *state;

err = json_scan(tmpctx, buf, channel,
Expand All @@ -314,30 +359,53 @@ static struct node_map *local_connected(const tal_t *ctx,

if (!is_connected)
continue;
private_tok = json_get_member(buf, channel, "private");
json_to_bool(buf, private_tok, &is_private);
scid_tok = json_get_member(buf, channel, "short_channel_id");
json_to_short_channel_id(buf, scid_tok, &scid);

/* Must also have a channel in CHANNELD_NORMAL/splice */
if (streq(state, "CHANNELD_NORMAL")
|| streq(state, "CHANNELD_AWAITING_SPLICE")) {
node_map_add(connected,
tal_dup(connected, struct node_id, &id));
if (is_private) {
struct private_channel *chan;
chan = private_channel_map_get(*private, &scid);
if (!chan) {
chan = tal(*private, struct private_channel);
private_channel_map_add(*private, chan);
}
/* FIXME: populate in correct position */
chan->nodes[0] = id;
chan->half_chan_data[0].delay = 40;
}
}
}

return connected;
}

/* We want to combine local knowledge to we know which are actually inactive! */
struct opts_and_privinbound {
struct listchannels_opts *opts;
const jsmntok_t *privinboundresult;
};

/* We want to combine local knowledge so we know which are actually inactive! */
static struct command_result *listpeerchannels_done(struct command *cmd,
const char *buf,
const jsmntok_t *result,
struct listchannels_opts *opts)
struct opts_and_privinbound *opts_and_inbound)
{
struct node_map *connected;
struct private_channel_map *private;
struct gossmap_chan *c;
struct json_stream *js;
struct gossmap *gossmap = get_gossmap();
struct listchannels_opts *opts = opts_and_inbound->opts;
const jsmntok_t *inbound_result = opts_and_inbound->privinboundresult;

connected = local_connected(opts, buf, result);
connected = local_connected(opts, buf, result, inbound_result, &private);

js = jsonrpc_stream_success(cmd);
json_array_start(js, "channels");
Expand Down Expand Up @@ -382,6 +450,24 @@ static struct command_result *listpeerchannels_done(struct command *cmd,
return command_finished(cmd, js);
}

/* Private channel gossip data must be retrieved from lightningd. */
static struct command_result *listchannels_privateinbound_done(struct command *cmd,
const char *buffer,
const jsmntok_t *result,
struct listchannels_opts *opts)
{
struct opts_and_privinbound *opts_and_inbound;
struct out_req *req;
opts_and_inbound = tal(cmd, struct opts_and_privinbound);
opts_and_inbound->opts = opts;
opts_and_inbound->privinboundresult = result;

req = jsonrpc_request_start(cmd->plugin, cmd, "listpeerchannels",
listpeerchannels_done, forward_error,
opts_and_inbound);
return send_outreq(cmd->plugin, req);
}

static struct command_result *json_listchannels(struct command *cmd,
const char *buffer,
const jsmntok_t *params)
Expand All @@ -402,8 +488,9 @@ static struct command_result *json_listchannels(struct command *cmd,
"Can only specify one of "
"`short_channel_id`, "
"`source` or `destination`");
req = jsonrpc_request_start(cmd->plugin, cmd, "listpeerchannels",
listpeerchannels_done, forward_error, opts);
req = jsonrpc_request_start(cmd->plugin, cmd, "listprivateinbound",
listchannels_privateinbound_done,
forward_error, opts);
return send_outreq(cmd->plugin, req);
}

Expand Down

0 comments on commit 2818316

Please sign in to comment.