mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 13:25:43 +01:00
gossipd: remove routing, listchannels and listnodes infrastructure.
This involves removing some fields from the now-misnamed routing.h datastructures, and various internal messages. One non-obvious change is to our "keepalive" logic which refreshes channels every 13 days: instead of using the 'enabled' flag on the last channel broadcast to decide whether to refresh it, we use the local connected status directly. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
8810ce7241
commit
7e7ab4cb3b
@ -11,6 +11,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <gossipd/gossip_generation.h>
|
#include <gossipd/gossip_generation.h>
|
||||||
#include <gossipd/gossip_store.h>
|
#include <gossipd/gossip_store.h>
|
||||||
|
#include <gossipd/gossip_store_wiregen.h>
|
||||||
#include <gossipd/gossipd.h>
|
#include <gossipd/gossipd.h>
|
||||||
#include <gossipd/gossipd_peerd_wiregen.h>
|
#include <gossipd/gossipd_peerd_wiregen.h>
|
||||||
#include <hsmd/hsmd_wiregen.h>
|
#include <hsmd/hsmd_wiregen.h>
|
||||||
@ -414,6 +415,12 @@ void refresh_local_channel(struct daemon *daemon,
|
|||||||
{
|
{
|
||||||
const struct half_chan *hc;
|
const struct half_chan *hc;
|
||||||
struct local_cupdate *lc;
|
struct local_cupdate *lc;
|
||||||
|
u8 *prev;
|
||||||
|
secp256k1_ecdsa_signature signature;
|
||||||
|
struct bitcoin_blkid chain_hash;
|
||||||
|
struct short_channel_id short_channel_id;
|
||||||
|
u32 timestamp;
|
||||||
|
u8 message_flags, channel_flags;
|
||||||
|
|
||||||
hc = &local_chan->chan->half[local_chan->direction];
|
hc = &local_chan->chan->half[local_chan->direction];
|
||||||
|
|
||||||
@ -425,14 +432,32 @@ void refresh_local_channel(struct daemon *daemon,
|
|||||||
lc->daemon = daemon;
|
lc->daemon = daemon;
|
||||||
lc->local_chan = local_chan;
|
lc->local_chan = local_chan;
|
||||||
lc->even_if_identical = even_if_identical;
|
lc->even_if_identical = even_if_identical;
|
||||||
lc->disable = (hc->channel_flags & ROUTING_FLAGS_DISABLED)
|
|
||||||
|| local_chan->local_disabled;
|
|
||||||
lc->cltv_expiry_delta = hc->delay;
|
|
||||||
lc->htlc_minimum = hc->htlc_minimum;
|
|
||||||
lc->htlc_maximum = hc->htlc_maximum;
|
|
||||||
lc->fee_base_msat = hc->base_fee;
|
|
||||||
lc->fee_proportional_millionths = hc->proportional_fee;
|
|
||||||
|
|
||||||
|
prev = cast_const(u8 *,
|
||||||
|
gossip_store_get(tmpctx, daemon->rstate->gs,
|
||||||
|
local_chan->chan->half[local_chan->direction]
|
||||||
|
.bcast.index));
|
||||||
|
|
||||||
|
/* If it's a private update, unwrap */
|
||||||
|
fromwire_gossip_store_private_update(tmpctx, prev, &prev);
|
||||||
|
|
||||||
|
if (!fromwire_channel_update_option_channel_htlc_max(prev,
|
||||||
|
&signature, &chain_hash,
|
||||||
|
&short_channel_id, ×tamp,
|
||||||
|
&message_flags, &channel_flags,
|
||||||
|
&lc->cltv_expiry_delta,
|
||||||
|
&lc->htlc_minimum,
|
||||||
|
&lc->fee_base_msat,
|
||||||
|
&lc->fee_proportional_millionths,
|
||||||
|
&lc->htlc_maximum)) {
|
||||||
|
status_broken("Could not decode local channel_update %s!",
|
||||||
|
tal_hex(tmpctx, prev));
|
||||||
|
tal_free(lc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lc->disable = (channel_flags & ROUTING_FLAGS_DISABLED)
|
||||||
|
|| local_chan->local_disabled;
|
||||||
update_local_channel(lc);
|
update_local_channel(lc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1025,7 +1025,7 @@ static void gossip_refresh_network(struct daemon *daemon)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_halfchan_enabled(hc)) {
|
if (is_chan_local_disabled(daemon->rstate, c)) {
|
||||||
/* Only send keepalives for active connections */
|
/* Only send keepalives for active connections */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1138,285 +1138,6 @@ static struct io_plan *gossip_init(struct io_conn *conn,
|
|||||||
return daemon_conn_read_next(conn, daemon->master);
|
return daemon_conn_read_next(conn, daemon->master);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*~ lightningd can ask for a route between nodes. */
|
|
||||||
static struct io_plan *getroute_req(struct io_conn *conn, struct daemon *daemon,
|
|
||||||
const u8 *msg)
|
|
||||||
{
|
|
||||||
struct node_id *source, destination;
|
|
||||||
struct amount_msat msat;
|
|
||||||
u32 final_cltv;
|
|
||||||
/* risk factor 12.345% -> riskfactor_millionths = 12345000 */
|
|
||||||
u64 riskfactor_millionths;
|
|
||||||
u32 max_hops;
|
|
||||||
u8 *out;
|
|
||||||
struct route_hop **hops;
|
|
||||||
/* fuzz 12.345% -> fuzz_millionths = 12345000 */
|
|
||||||
u64 fuzz_millionths;
|
|
||||||
struct exclude_entry **excluded;
|
|
||||||
|
|
||||||
/* To choose between variations, we need to know how much we're
|
|
||||||
* sending (eliminates too-small channels, and also effects the fees
|
|
||||||
* we'll pay), how to trade off more locktime vs. more fees, and how
|
|
||||||
* much cltv we need a the final node to give exact values for each
|
|
||||||
* intermediate hop, as well as how much random fuzz to inject to
|
|
||||||
* avoid being too predictable.
|
|
||||||
*
|
|
||||||
* We also treat routing slightly differently if we're asking
|
|
||||||
* for a route from ourselves (the usual case): in that case,
|
|
||||||
* we don't have to consider fees on our own outgoing channels.
|
|
||||||
*/
|
|
||||||
if (!fromwire_gossipd_getroute_request(
|
|
||||||
msg, msg, &source, &destination, &msat, &riskfactor_millionths,
|
|
||||||
&final_cltv, &fuzz_millionths, &excluded, &max_hops))
|
|
||||||
master_badmsg(WIRE_GOSSIPD_GETROUTE_REQUEST, msg);
|
|
||||||
|
|
||||||
status_debug("Trying to find a route from %s to %s for %s",
|
|
||||||
source
|
|
||||||
? type_to_string(tmpctx, struct node_id, source) : "(me)",
|
|
||||||
type_to_string(tmpctx, struct node_id, &destination),
|
|
||||||
type_to_string(tmpctx, struct amount_msat, &msat));
|
|
||||||
|
|
||||||
/* routing.c does all the hard work; can return NULL. */
|
|
||||||
hops = get_route(tmpctx, daemon->rstate, source, &destination, msat,
|
|
||||||
riskfactor_millionths / 1000000.0, final_cltv,
|
|
||||||
fuzz_millionths / 1000000.0, pseudorand_u64(),
|
|
||||||
excluded, max_hops);
|
|
||||||
|
|
||||||
out = towire_gossipd_getroute_reply(NULL,
|
|
||||||
cast_const2(const struct route_hop **,
|
|
||||||
hops));
|
|
||||||
daemon_conn_send(daemon->master, take(out));
|
|
||||||
return daemon_conn_read_next(conn, daemon->master);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*~ When someone asks lightningd to `listchannels`, gossipd does the work:
|
|
||||||
* marshalling the channel information for all channels into an array of
|
|
||||||
* gossip_getchannels_entry, which lightningd converts to JSON. Each channel
|
|
||||||
* is represented by two half_chan; one in each direction.
|
|
||||||
*/
|
|
||||||
static struct gossip_halfchannel_entry *hc_entry(const tal_t *ctx,
|
|
||||||
const struct chan *chan,
|
|
||||||
int idx)
|
|
||||||
{
|
|
||||||
/* Our 'struct chan' contains two nodes: they are in pubkey_cmp order
|
|
||||||
* (ie. chan->nodes[0] is the lesser pubkey) and this is the same as
|
|
||||||
* the direction bit in `channel_update`s `channel_flags`.
|
|
||||||
*
|
|
||||||
* The halfchans are arranged so that half[0] src == nodes[0], and we
|
|
||||||
* use that here. */
|
|
||||||
const struct half_chan *c = &chan->half[idx];
|
|
||||||
struct gossip_halfchannel_entry *e;
|
|
||||||
|
|
||||||
/* If we've never seen a channel_update for this direction... */
|
|
||||||
if (!is_halfchan_defined(c))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
e = tal(ctx, struct gossip_halfchannel_entry);
|
|
||||||
e->channel_flags = c->channel_flags;
|
|
||||||
e->message_flags = c->message_flags;
|
|
||||||
e->last_update_timestamp = c->bcast.timestamp;
|
|
||||||
e->base_fee_msat = c->base_fee;
|
|
||||||
e->fee_per_millionth = c->proportional_fee;
|
|
||||||
e->delay = c->delay;
|
|
||||||
e->min = c->htlc_minimum;
|
|
||||||
e->max = c->htlc_maximum;
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*~ We don't keep channel features in memory; they're rarely used. So we
|
|
||||||
* remember if it exists, and load it off disk when needed. */
|
|
||||||
static u8 *get_channel_features(const tal_t *ctx,
|
|
||||||
struct gossip_store *gs,
|
|
||||||
const struct chan *chan)
|
|
||||||
{
|
|
||||||
secp256k1_ecdsa_signature sig;
|
|
||||||
u8 *features;
|
|
||||||
struct bitcoin_blkid chain_hash;
|
|
||||||
struct short_channel_id short_channel_id;
|
|
||||||
struct node_id node_id;
|
|
||||||
struct pubkey bitcoin_key;
|
|
||||||
struct amount_sat sats;
|
|
||||||
u8 *ann;
|
|
||||||
|
|
||||||
/* This is where we stash a flag to indicate it exists. */
|
|
||||||
if (!chan->half[0].any_features)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
ann = cast_const(u8 *, gossip_store_get(tmpctx, gs, chan->bcast.index));
|
|
||||||
|
|
||||||
/* Could be a private_channel */
|
|
||||||
fromwire_gossip_store_private_channel(tmpctx, ann, &sats, &ann);
|
|
||||||
|
|
||||||
if (!fromwire_channel_announcement(ctx, ann, &sig, &sig, &sig, &sig,
|
|
||||||
&features, &chain_hash,
|
|
||||||
&short_channel_id,
|
|
||||||
&node_id, &node_id,
|
|
||||||
&bitcoin_key, &bitcoin_key))
|
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
||||||
"bad channel_announcement / local_add_channel at %u: %s",
|
|
||||||
chan->bcast.index, tal_hex(tmpctx, ann));
|
|
||||||
|
|
||||||
return features;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*~ Marshal (possibly) both channel directions into entries. */
|
|
||||||
static void append_channel(struct routing_state *rstate,
|
|
||||||
const struct gossip_getchannels_entry ***entries,
|
|
||||||
const struct chan *chan,
|
|
||||||
const struct node_id *srcfilter)
|
|
||||||
{
|
|
||||||
struct gossip_getchannels_entry *e = tal(*entries, struct gossip_getchannels_entry);
|
|
||||||
|
|
||||||
e->node[0] = chan->nodes[0]->id;
|
|
||||||
e->node[1] = chan->nodes[1]->id;
|
|
||||||
e->sat = chan->sat;
|
|
||||||
e->local_disabled = is_chan_local_disabled(rstate, chan);
|
|
||||||
e->public = is_chan_public(chan);
|
|
||||||
e->short_channel_id = chan->scid;
|
|
||||||
e->features = get_channel_features(e, rstate->gs, chan);
|
|
||||||
if (!srcfilter || node_id_eq(&e->node[0], srcfilter))
|
|
||||||
e->e[0] = hc_entry(*entries, chan, 0);
|
|
||||||
else
|
|
||||||
e->e[0] = NULL;
|
|
||||||
if (!srcfilter || node_id_eq(&e->node[1], srcfilter))
|
|
||||||
e->e[1] = hc_entry(*entries, chan, 1);
|
|
||||||
else
|
|
||||||
e->e[1] = NULL;
|
|
||||||
|
|
||||||
/* We choose not to tell lightningd about channels with no updates,
|
|
||||||
* as they're unusable and can't be represented in the listchannels
|
|
||||||
* JSON output we use anyway. */
|
|
||||||
if (e->e[0] || e->e[1])
|
|
||||||
tal_arr_expand(entries, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*~ This is where lightningd asks for all channels we know about. */
|
|
||||||
static struct io_plan *getchannels_req(struct io_conn *conn,
|
|
||||||
struct daemon *daemon,
|
|
||||||
const u8 *msg)
|
|
||||||
{
|
|
||||||
u8 *out;
|
|
||||||
const struct gossip_getchannels_entry **entries;
|
|
||||||
struct chan *chan;
|
|
||||||
struct short_channel_id *scid, *prev;
|
|
||||||
struct node_id *source;
|
|
||||||
bool complete = true;
|
|
||||||
|
|
||||||
/* Note: scid is marked optional in gossip_wire.csv */
|
|
||||||
if (!fromwire_gossipd_getchannels_request(msg, msg, &scid, &source,
|
|
||||||
&prev))
|
|
||||||
master_badmsg(WIRE_GOSSIPD_GETCHANNELS_REQUEST, msg);
|
|
||||||
|
|
||||||
entries = tal_arr(tmpctx, const struct gossip_getchannels_entry *, 0);
|
|
||||||
/* They can ask about a particular channel by short_channel_id */
|
|
||||||
if (scid) {
|
|
||||||
chan = get_channel(daemon->rstate, scid);
|
|
||||||
if (chan)
|
|
||||||
append_channel(daemon->rstate, &entries, chan, NULL);
|
|
||||||
} else if (source) {
|
|
||||||
struct node *s = get_node(daemon->rstate, source);
|
|
||||||
if (s) {
|
|
||||||
struct chan_map_iter i;
|
|
||||||
struct chan *c;
|
|
||||||
|
|
||||||
for (c = first_chan(s, &i); c; c = next_chan(s, &i)) {
|
|
||||||
append_channel(daemon->rstate,
|
|
||||||
&entries, c, source);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
u64 idx;
|
|
||||||
|
|
||||||
/* For the more general case, we just iterate through every
|
|
||||||
* short channel id, starting with previous if any (there is
|
|
||||||
* no scid 0). */
|
|
||||||
idx = prev ? prev->u64 : 0;
|
|
||||||
while ((chan = uintmap_after(&daemon->rstate->chanmap, &idx))) {
|
|
||||||
append_channel(daemon->rstate, &entries, chan, NULL);
|
|
||||||
/* Limit how many we do at once. */
|
|
||||||
if (tal_count(entries) == 4096) {
|
|
||||||
complete = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out = towire_gossipd_getchannels_reply(NULL, complete, entries);
|
|
||||||
daemon_conn_send(daemon->master, take(out));
|
|
||||||
return daemon_conn_read_next(conn, daemon->master);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*~ Similarly, lightningd asks us for all nodes when it gets `listnodes` */
|
|
||||||
/* We keep pointers into n, assuming it won't change. */
|
|
||||||
static void add_node_entry(const tal_t *ctx,
|
|
||||||
struct daemon *daemon,
|
|
||||||
const struct node *n,
|
|
||||||
struct gossip_getnodes_entry *e)
|
|
||||||
{
|
|
||||||
e->nodeid = n->id;
|
|
||||||
if (get_node_announcement(ctx, daemon, n,
|
|
||||||
e->color, e->alias,
|
|
||||||
&e->features,
|
|
||||||
&e->addresses)) {
|
|
||||||
e->last_timestamp = n->bcast.timestamp;
|
|
||||||
} else {
|
|
||||||
/* Timestamp on wire is an unsigned 32 bit: we use a 64-bit
|
|
||||||
* signed, so -1 means "we never received a
|
|
||||||
* channel_update". */
|
|
||||||
e->last_timestamp = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Simply routine when they ask for `listnodes` */
|
|
||||||
static struct io_plan *getnodes(struct io_conn *conn, struct daemon *daemon,
|
|
||||||
const u8 *msg)
|
|
||||||
{
|
|
||||||
u8 *out;
|
|
||||||
struct node *n;
|
|
||||||
const struct gossip_getnodes_entry **nodes;
|
|
||||||
struct gossip_getnodes_entry *node_arr;
|
|
||||||
struct node_id *id;
|
|
||||||
|
|
||||||
if (!fromwire_gossipd_getnodes_request(tmpctx, msg, &id))
|
|
||||||
master_badmsg(WIRE_GOSSIPD_GETNODES_REQUEST, msg);
|
|
||||||
|
|
||||||
/* Format of reply is the same whether they ask for a specific node
|
|
||||||
* (0 or one responses) or all nodes (0 or more) */
|
|
||||||
if (id) {
|
|
||||||
n = get_node(daemon->rstate, id);
|
|
||||||
if (n) {
|
|
||||||
node_arr = tal_arr(tmpctx,
|
|
||||||
struct gossip_getnodes_entry,
|
|
||||||
1);
|
|
||||||
add_node_entry(node_arr, daemon, n, &node_arr[0]);
|
|
||||||
} else {
|
|
||||||
nodes = NULL;
|
|
||||||
node_arr = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
struct node_map_iter it;
|
|
||||||
size_t i = 0;
|
|
||||||
node_arr = tal_arr(tmpctx, struct gossip_getnodes_entry,
|
|
||||||
node_map_count(daemon->rstate->nodes));
|
|
||||||
n = node_map_first(daemon->rstate->nodes, &it);
|
|
||||||
while (n != NULL) {
|
|
||||||
add_node_entry(node_arr, daemon, n, &node_arr[i++]);
|
|
||||||
n = node_map_next(daemon->rstate->nodes, &it);
|
|
||||||
}
|
|
||||||
assert(i == node_map_count(daemon->rstate->nodes));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: towire wants array of pointers. */
|
|
||||||
nodes = tal_arr(tmpctx, const struct gossip_getnodes_entry *,
|
|
||||||
tal_count(node_arr));
|
|
||||||
for (size_t i = 0; i < tal_count(node_arr); i++)
|
|
||||||
nodes[i] = &node_arr[i];
|
|
||||||
out = towire_gossipd_getnodes_reply(NULL, nodes);
|
|
||||||
daemon_conn_send(daemon->master, take(out));
|
|
||||||
return daemon_conn_read_next(conn, daemon->master);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*~ We currently have a JSON command to ping a peer: it ends up here, where
|
/*~ We currently have a JSON command to ping a peer: it ends up here, where
|
||||||
* gossipd generates the actual ping and sends it like any other gossip. */
|
* gossipd generates the actual ping and sends it like any other gossip. */
|
||||||
static struct io_plan *ping_req(struct io_conn *conn, struct daemon *daemon,
|
static struct io_plan *ping_req(struct io_conn *conn, struct daemon *daemon,
|
||||||
@ -1472,81 +1193,6 @@ out:
|
|||||||
return daemon_conn_read_next(conn, daemon->master);
|
return daemon_conn_read_next(conn, daemon->master);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*~ If a node has no public channels (other than the one to us), it's not
|
|
||||||
* a very useful route to tell anyone about. */
|
|
||||||
static bool node_has_public_channels(const struct node *peer,
|
|
||||||
const struct chan *exclude)
|
|
||||||
{
|
|
||||||
struct chan_map_iter i;
|
|
||||||
struct chan *c;
|
|
||||||
|
|
||||||
for (c = first_chan(peer, &i); c; c = next_chan(peer, &i)) {
|
|
||||||
if (c == exclude)
|
|
||||||
continue;
|
|
||||||
if (is_chan_public(c))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*~ 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
|
|
||||||
* current capacities, so lightningd selects which to use. */
|
|
||||||
static struct io_plan *get_incoming_channels(struct io_conn *conn,
|
|
||||||
struct daemon *daemon,
|
|
||||||
const u8 *msg)
|
|
||||||
{
|
|
||||||
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 *priv_deadends = tal_arr(tmpctx, bool, 0);
|
|
||||||
bool *pub_deadends = tal_arr(tmpctx, bool, 0);
|
|
||||||
|
|
||||||
if (!fromwire_gossipd_get_incoming_channels(msg))
|
|
||||||
master_badmsg(WIRE_GOSSIPD_GET_INCOMING_CHANNELS, msg);
|
|
||||||
|
|
||||||
node = get_node(daemon->rstate, &daemon->rstate->local_id);
|
|
||||||
if (node) {
|
|
||||||
struct chan_map_iter i;
|
|
||||||
struct chan *c;
|
|
||||||
|
|
||||||
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)];
|
|
||||||
|
|
||||||
if (!is_halfchan_enabled(hc))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ri.pubkey = other_node(node, c)->id;
|
|
||||||
ri.short_channel_id = c->scid;
|
|
||||||
ri.fee_base_msat = hc->base_fee;
|
|
||||||
ri.fee_proportional_millionths = hc->proportional_fee;
|
|
||||||
ri.cltv_expiry_delta = hc->delay;
|
|
||||||
|
|
||||||
deadend = !node_has_public_channels(other_node(node, c),
|
|
||||||
c);
|
|
||||||
if (is_chan_public(c)) {
|
|
||||||
tal_arr_expand(&public, ri);
|
|
||||||
tal_arr_expand(&pub_deadends, deadend);
|
|
||||||
} else {
|
|
||||||
tal_arr_expand(&private, ri);
|
|
||||||
tal_arr_expand(&priv_deadends, deadend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = towire_gossipd_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct io_plan *new_blockheight(struct io_conn *conn,
|
static struct io_plan *new_blockheight(struct io_conn *conn,
|
||||||
struct daemon *daemon,
|
struct daemon *daemon,
|
||||||
const u8 *msg)
|
const u8 *msg)
|
||||||
@ -1816,15 +1462,6 @@ static struct io_plan *recv_req(struct io_conn *conn,
|
|||||||
case WIRE_GOSSIPD_INIT:
|
case WIRE_GOSSIPD_INIT:
|
||||||
return gossip_init(conn, daemon, msg);
|
return gossip_init(conn, daemon, msg);
|
||||||
|
|
||||||
case WIRE_GOSSIPD_GETNODES_REQUEST:
|
|
||||||
return getnodes(conn, daemon, msg);
|
|
||||||
|
|
||||||
case WIRE_GOSSIPD_GETROUTE_REQUEST:
|
|
||||||
return getroute_req(conn, daemon, msg);
|
|
||||||
|
|
||||||
case WIRE_GOSSIPD_GETCHANNELS_REQUEST:
|
|
||||||
return getchannels_req(conn, daemon, msg);
|
|
||||||
|
|
||||||
case WIRE_GOSSIPD_GET_STRIPPED_CUPDATE:
|
case WIRE_GOSSIPD_GET_STRIPPED_CUPDATE:
|
||||||
return get_stripped_cupdate(conn, daemon, msg);
|
return get_stripped_cupdate(conn, daemon, msg);
|
||||||
|
|
||||||
@ -1840,9 +1477,6 @@ static struct io_plan *recv_req(struct io_conn *conn,
|
|||||||
case WIRE_GOSSIPD_PING:
|
case WIRE_GOSSIPD_PING:
|
||||||
return ping_req(conn, daemon, msg);
|
return ping_req(conn, daemon, msg);
|
||||||
|
|
||||||
case WIRE_GOSSIPD_GET_INCOMING_CHANNELS:
|
|
||||||
return get_incoming_channels(conn, daemon, msg);
|
|
||||||
|
|
||||||
case WIRE_GOSSIPD_NEW_BLOCKHEIGHT:
|
case WIRE_GOSSIPD_NEW_BLOCKHEIGHT:
|
||||||
return new_blockheight(conn, daemon, msg);
|
return new_blockheight(conn, daemon, msg);
|
||||||
|
|
||||||
@ -1872,12 +1506,8 @@ static struct io_plan *recv_req(struct io_conn *conn,
|
|||||||
case WIRE_GOSSIPD_SEND_ONIONMSG:
|
case WIRE_GOSSIPD_SEND_ONIONMSG:
|
||||||
return onionmsg_req(conn, daemon, msg);
|
return onionmsg_req(conn, daemon, msg);
|
||||||
/* We send these, we don't receive them */
|
/* We send these, we don't receive them */
|
||||||
case WIRE_GOSSIPD_GETNODES_REPLY:
|
|
||||||
case WIRE_GOSSIPD_GETROUTE_REPLY:
|
|
||||||
case WIRE_GOSSIPD_GETCHANNELS_REPLY:
|
|
||||||
case WIRE_GOSSIPD_PING_REPLY:
|
case WIRE_GOSSIPD_PING_REPLY:
|
||||||
case WIRE_GOSSIPD_GET_STRIPPED_CUPDATE_REPLY:
|
case WIRE_GOSSIPD_GET_STRIPPED_CUPDATE_REPLY:
|
||||||
case WIRE_GOSSIPD_GET_INCOMING_CHANNELS_REPLY:
|
|
||||||
case WIRE_GOSSIPD_GET_TXOUT:
|
case WIRE_GOSSIPD_GET_TXOUT:
|
||||||
case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY:
|
case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY:
|
||||||
case WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY:
|
case WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY:
|
||||||
|
@ -20,42 +20,6 @@ msgdata,gossipd_init,dev_fast_gossip_prune,bool,
|
|||||||
msgtype,gossipd_dev_set_time,3001
|
msgtype,gossipd_dev_set_time,3001
|
||||||
msgdata,gossipd_dev_set_time,dev_gossip_time,u32,
|
msgdata,gossipd_dev_set_time,dev_gossip_time,u32,
|
||||||
|
|
||||||
# Pass JSON-RPC getnodes call through
|
|
||||||
msgtype,gossipd_getnodes_request,3005
|
|
||||||
msgdata,gossipd_getnodes_request,id,?node_id,
|
|
||||||
|
|
||||||
#include <lightningd/gossip_msg.h>
|
|
||||||
msgtype,gossipd_getnodes_reply,3105
|
|
||||||
msgdata,gossipd_getnodes_reply,num_nodes,u32,
|
|
||||||
msgdata,gossipd_getnodes_reply,nodes,gossip_getnodes_entry,num_nodes
|
|
||||||
|
|
||||||
# Pass JSON-RPC getroute call through
|
|
||||||
msgtype,gossipd_getroute_request,3006
|
|
||||||
# Source defaults to "us", and means we don't consider first-hop channel fees
|
|
||||||
msgdata,gossipd_getroute_request,source,?node_id,
|
|
||||||
msgdata,gossipd_getroute_request,destination,node_id,
|
|
||||||
msgdata,gossipd_getroute_request,msatoshi,amount_msat,
|
|
||||||
msgdata,gossipd_getroute_request,riskfactor_millionths,u64,
|
|
||||||
msgdata,gossipd_getroute_request,final_cltv,u32,
|
|
||||||
msgdata,gossipd_getroute_request,fuzz_millionths,u64,
|
|
||||||
msgdata,gossipd_getroute_request,num_excluded,u16,
|
|
||||||
msgdata,gossipd_getroute_request,excluded,exclude_entry,num_excluded
|
|
||||||
msgdata,gossipd_getroute_request,max_hops,u32,
|
|
||||||
|
|
||||||
msgtype,gossipd_getroute_reply,3106
|
|
||||||
msgdata,gossipd_getroute_reply,num_hops,u16,
|
|
||||||
msgdata,gossipd_getroute_reply,hops,route_hop,num_hops
|
|
||||||
|
|
||||||
msgtype,gossipd_getchannels_request,3007
|
|
||||||
msgdata,gossipd_getchannels_request,short_channel_id,?short_channel_id,
|
|
||||||
msgdata,gossipd_getchannels_request,source,?node_id,
|
|
||||||
msgdata,gossipd_getchannels_request,prev,?short_channel_id,
|
|
||||||
|
|
||||||
msgtype,gossipd_getchannels_reply,3107
|
|
||||||
msgdata,gossipd_getchannels_reply,complete,bool,
|
|
||||||
msgdata,gossipd_getchannels_reply,num_channels,u32,
|
|
||||||
msgdata,gossipd_getchannels_reply,nodes,gossip_getchannels_entry,num_channels
|
|
||||||
|
|
||||||
# Ping/pong test. Waits for a reply if it expects one.
|
# Ping/pong test. Waits for a reply if it expects one.
|
||||||
msgtype,gossipd_ping,3008
|
msgtype,gossipd_ping,3008
|
||||||
msgdata,gossipd_ping,id,node_id,
|
msgdata,gossipd_ping,id,node_id,
|
||||||
@ -116,20 +80,6 @@ msgtype,gossipd_dev_compact_store,3034
|
|||||||
msgtype,gossipd_dev_compact_store_reply,3134
|
msgtype,gossipd_dev_compact_store_reply,3134
|
||||||
msgdata,gossipd_dev_compact_store_reply,success,bool,
|
msgdata,gossipd_dev_compact_store_reply,success,bool,
|
||||||
|
|
||||||
#include <common/bolt11.h>
|
|
||||||
|
|
||||||
# master -> gossipd: get route_info for our incoming channels
|
|
||||||
msgtype,gossipd_get_incoming_channels,3025
|
|
||||||
|
|
||||||
# gossipd -> master: here they are.
|
|
||||||
msgtype,gossipd_get_incoming_channels_reply,3125
|
|
||||||
msgdata,gossipd_get_incoming_channels_reply,num_public,u16,
|
|
||||||
msgdata,gossipd_get_incoming_channels_reply,public_route_info,route_info,num_public
|
|
||||||
msgdata,gossipd_get_incoming_channels_reply,public_deadends,bool,num_public
|
|
||||||
msgdata,gossipd_get_incoming_channels_reply,num_private,u16,
|
|
||||||
msgdata,gossipd_get_incoming_channels_reply,private_route_info,route_info,num_private
|
|
||||||
msgdata,gossipd_get_incoming_channels_reply,private_deadends,bool,num_private
|
|
||||||
|
|
||||||
# master -> gossipd: blockheight increased.
|
# master -> gossipd: blockheight increased.
|
||||||
msgtype,gossipd_new_blockheight,3026
|
msgtype,gossipd_new_blockheight,3026
|
||||||
msgdata,gossipd_new_blockheight,blockheight,u32,
|
msgdata,gossipd_new_blockheight,blockheight,u32,
|
||||||
|
Can't render this file because it has a wrong number of fields in line 7.
|
327
gossipd/gossipd_wiregen.c
generated
327
gossipd/gossipd_wiregen.c
generated
@ -22,12 +22,6 @@ const char *gossipd_wire_name(int e)
|
|||||||
switch ((enum gossipd_wire)e) {
|
switch ((enum gossipd_wire)e) {
|
||||||
case WIRE_GOSSIPD_INIT: return "WIRE_GOSSIPD_INIT";
|
case WIRE_GOSSIPD_INIT: return "WIRE_GOSSIPD_INIT";
|
||||||
case WIRE_GOSSIPD_DEV_SET_TIME: return "WIRE_GOSSIPD_DEV_SET_TIME";
|
case WIRE_GOSSIPD_DEV_SET_TIME: return "WIRE_GOSSIPD_DEV_SET_TIME";
|
||||||
case WIRE_GOSSIPD_GETNODES_REQUEST: return "WIRE_GOSSIPD_GETNODES_REQUEST";
|
|
||||||
case WIRE_GOSSIPD_GETNODES_REPLY: return "WIRE_GOSSIPD_GETNODES_REPLY";
|
|
||||||
case WIRE_GOSSIPD_GETROUTE_REQUEST: return "WIRE_GOSSIPD_GETROUTE_REQUEST";
|
|
||||||
case WIRE_GOSSIPD_GETROUTE_REPLY: return "WIRE_GOSSIPD_GETROUTE_REPLY";
|
|
||||||
case WIRE_GOSSIPD_GETCHANNELS_REQUEST: return "WIRE_GOSSIPD_GETCHANNELS_REQUEST";
|
|
||||||
case WIRE_GOSSIPD_GETCHANNELS_REPLY: return "WIRE_GOSSIPD_GETCHANNELS_REPLY";
|
|
||||||
case WIRE_GOSSIPD_PING: return "WIRE_GOSSIPD_PING";
|
case WIRE_GOSSIPD_PING: return "WIRE_GOSSIPD_PING";
|
||||||
case WIRE_GOSSIPD_PING_REPLY: return "WIRE_GOSSIPD_PING_REPLY";
|
case WIRE_GOSSIPD_PING_REPLY: return "WIRE_GOSSIPD_PING_REPLY";
|
||||||
case WIRE_GOSSIPD_DEV_SET_MAX_SCIDS_ENCODE_SIZE: return "WIRE_GOSSIPD_DEV_SET_MAX_SCIDS_ENCODE_SIZE";
|
case WIRE_GOSSIPD_DEV_SET_MAX_SCIDS_ENCODE_SIZE: return "WIRE_GOSSIPD_DEV_SET_MAX_SCIDS_ENCODE_SIZE";
|
||||||
@ -42,8 +36,6 @@ const char *gossipd_wire_name(int e)
|
|||||||
case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY: return "WIRE_GOSSIPD_DEV_MEMLEAK_REPLY";
|
case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY: return "WIRE_GOSSIPD_DEV_MEMLEAK_REPLY";
|
||||||
case WIRE_GOSSIPD_DEV_COMPACT_STORE: return "WIRE_GOSSIPD_DEV_COMPACT_STORE";
|
case WIRE_GOSSIPD_DEV_COMPACT_STORE: return "WIRE_GOSSIPD_DEV_COMPACT_STORE";
|
||||||
case WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY: return "WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY";
|
case WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY: return "WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY";
|
||||||
case WIRE_GOSSIPD_GET_INCOMING_CHANNELS: return "WIRE_GOSSIPD_GET_INCOMING_CHANNELS";
|
|
||||||
case WIRE_GOSSIPD_GET_INCOMING_CHANNELS_REPLY: return "WIRE_GOSSIPD_GET_INCOMING_CHANNELS_REPLY";
|
|
||||||
case WIRE_GOSSIPD_NEW_BLOCKHEIGHT: return "WIRE_GOSSIPD_NEW_BLOCKHEIGHT";
|
case WIRE_GOSSIPD_NEW_BLOCKHEIGHT: return "WIRE_GOSSIPD_NEW_BLOCKHEIGHT";
|
||||||
case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US: return "WIRE_GOSSIPD_GOT_ONIONMSG_TO_US";
|
case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US: return "WIRE_GOSSIPD_GOT_ONIONMSG_TO_US";
|
||||||
case WIRE_GOSSIPD_GOT_ONIONMSG_FORWARD: return "WIRE_GOSSIPD_GOT_ONIONMSG_FORWARD";
|
case WIRE_GOSSIPD_GOT_ONIONMSG_FORWARD: return "WIRE_GOSSIPD_GOT_ONIONMSG_FORWARD";
|
||||||
@ -61,12 +53,6 @@ bool gossipd_wire_is_defined(u16 type)
|
|||||||
switch ((enum gossipd_wire)type) {
|
switch ((enum gossipd_wire)type) {
|
||||||
case WIRE_GOSSIPD_INIT:;
|
case WIRE_GOSSIPD_INIT:;
|
||||||
case WIRE_GOSSIPD_DEV_SET_TIME:;
|
case WIRE_GOSSIPD_DEV_SET_TIME:;
|
||||||
case WIRE_GOSSIPD_GETNODES_REQUEST:;
|
|
||||||
case WIRE_GOSSIPD_GETNODES_REPLY:;
|
|
||||||
case WIRE_GOSSIPD_GETROUTE_REQUEST:;
|
|
||||||
case WIRE_GOSSIPD_GETROUTE_REPLY:;
|
|
||||||
case WIRE_GOSSIPD_GETCHANNELS_REQUEST:;
|
|
||||||
case WIRE_GOSSIPD_GETCHANNELS_REPLY:;
|
|
||||||
case WIRE_GOSSIPD_PING:;
|
case WIRE_GOSSIPD_PING:;
|
||||||
case WIRE_GOSSIPD_PING_REPLY:;
|
case WIRE_GOSSIPD_PING_REPLY:;
|
||||||
case WIRE_GOSSIPD_DEV_SET_MAX_SCIDS_ENCODE_SIZE:;
|
case WIRE_GOSSIPD_DEV_SET_MAX_SCIDS_ENCODE_SIZE:;
|
||||||
@ -81,8 +67,6 @@ bool gossipd_wire_is_defined(u16 type)
|
|||||||
case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY:;
|
case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY:;
|
||||||
case WIRE_GOSSIPD_DEV_COMPACT_STORE:;
|
case WIRE_GOSSIPD_DEV_COMPACT_STORE:;
|
||||||
case WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY:;
|
case WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY:;
|
||||||
case WIRE_GOSSIPD_GET_INCOMING_CHANNELS:;
|
|
||||||
case WIRE_GOSSIPD_GET_INCOMING_CHANNELS_REPLY:;
|
|
||||||
case WIRE_GOSSIPD_NEW_BLOCKHEIGHT:;
|
case WIRE_GOSSIPD_NEW_BLOCKHEIGHT:;
|
||||||
case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US:;
|
case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US:;
|
||||||
case WIRE_GOSSIPD_GOT_ONIONMSG_FORWARD:;
|
case WIRE_GOSSIPD_GOT_ONIONMSG_FORWARD:;
|
||||||
@ -177,242 +161,6 @@ bool fromwire_gossipd_dev_set_time(const void *p, u32 *dev_gossip_time)
|
|||||||
return cursor != NULL;
|
return cursor != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GETNODES_REQUEST */
|
|
||||||
/* Pass JSON-RPC getnodes call through */
|
|
||||||
u8 *towire_gossipd_getnodes_request(const tal_t *ctx, const struct node_id *id)
|
|
||||||
{
|
|
||||||
u8 *p = tal_arr(ctx, u8, 0);
|
|
||||||
|
|
||||||
towire_u16(&p, WIRE_GOSSIPD_GETNODES_REQUEST);
|
|
||||||
if (!id)
|
|
||||||
towire_bool(&p, false);
|
|
||||||
else {
|
|
||||||
towire_bool(&p, true);
|
|
||||||
towire_node_id(&p, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return memcheck(p, tal_count(p));
|
|
||||||
}
|
|
||||||
bool fromwire_gossipd_getnodes_request(const tal_t *ctx, const void *p, struct node_id **id)
|
|
||||||
{
|
|
||||||
const u8 *cursor = p;
|
|
||||||
size_t plen = tal_count(p);
|
|
||||||
|
|
||||||
if (fromwire_u16(&cursor, &plen) != WIRE_GOSSIPD_GETNODES_REQUEST)
|
|
||||||
return false;
|
|
||||||
if (!fromwire_bool(&cursor, &plen))
|
|
||||||
*id = NULL;
|
|
||||||
else {
|
|
||||||
*id = tal(ctx, struct node_id);
|
|
||||||
fromwire_node_id(&cursor, &plen, *id);
|
|
||||||
}
|
|
||||||
return cursor != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GETNODES_REPLY */
|
|
||||||
u8 *towire_gossipd_getnodes_reply(const tal_t *ctx, const struct gossip_getnodes_entry **nodes)
|
|
||||||
{
|
|
||||||
u32 num_nodes = tal_count(nodes);
|
|
||||||
u8 *p = tal_arr(ctx, u8, 0);
|
|
||||||
|
|
||||||
towire_u16(&p, WIRE_GOSSIPD_GETNODES_REPLY);
|
|
||||||
towire_u32(&p, num_nodes);
|
|
||||||
for (size_t i = 0; i < num_nodes; i++)
|
|
||||||
towire_gossip_getnodes_entry(&p, nodes[i]);
|
|
||||||
|
|
||||||
return memcheck(p, tal_count(p));
|
|
||||||
}
|
|
||||||
bool fromwire_gossipd_getnodes_reply(const tal_t *ctx, const void *p, struct gossip_getnodes_entry ***nodes)
|
|
||||||
{
|
|
||||||
u32 num_nodes;
|
|
||||||
|
|
||||||
const u8 *cursor = p;
|
|
||||||
size_t plen = tal_count(p);
|
|
||||||
|
|
||||||
if (fromwire_u16(&cursor, &plen) != WIRE_GOSSIPD_GETNODES_REPLY)
|
|
||||||
return false;
|
|
||||||
num_nodes = fromwire_u32(&cursor, &plen);
|
|
||||||
// 2nd case nodes
|
|
||||||
*nodes = num_nodes ? tal_arr(ctx, struct gossip_getnodes_entry *, num_nodes) : NULL;
|
|
||||||
for (size_t i = 0; i < num_nodes; i++)
|
|
||||||
(*nodes)[i] = fromwire_gossip_getnodes_entry(*nodes, &cursor, &plen);
|
|
||||||
return cursor != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GETROUTE_REQUEST */
|
|
||||||
/* Pass JSON-RPC getroute call through */
|
|
||||||
u8 *towire_gossipd_getroute_request(const tal_t *ctx, const struct node_id *source, const struct node_id *destination, struct amount_msat msatoshi, u64 riskfactor_millionths, u32 final_cltv, u64 fuzz_millionths, const struct exclude_entry **excluded, u32 max_hops)
|
|
||||||
{
|
|
||||||
u16 num_excluded = tal_count(excluded);
|
|
||||||
u8 *p = tal_arr(ctx, u8, 0);
|
|
||||||
|
|
||||||
towire_u16(&p, WIRE_GOSSIPD_GETROUTE_REQUEST);
|
|
||||||
/* Source defaults to "us" */
|
|
||||||
if (!source)
|
|
||||||
towire_bool(&p, false);
|
|
||||||
else {
|
|
||||||
towire_bool(&p, true);
|
|
||||||
towire_node_id(&p, source);
|
|
||||||
}
|
|
||||||
towire_node_id(&p, destination);
|
|
||||||
towire_amount_msat(&p, msatoshi);
|
|
||||||
towire_u64(&p, riskfactor_millionths);
|
|
||||||
towire_u32(&p, final_cltv);
|
|
||||||
towire_u64(&p, fuzz_millionths);
|
|
||||||
towire_u16(&p, num_excluded);
|
|
||||||
for (size_t i = 0; i < num_excluded; i++)
|
|
||||||
towire_exclude_entry(&p, excluded[i]);
|
|
||||||
towire_u32(&p, max_hops);
|
|
||||||
|
|
||||||
return memcheck(p, tal_count(p));
|
|
||||||
}
|
|
||||||
bool fromwire_gossipd_getroute_request(const tal_t *ctx, const void *p, struct node_id **source, struct node_id *destination, struct amount_msat *msatoshi, u64 *riskfactor_millionths, u32 *final_cltv, u64 *fuzz_millionths, struct exclude_entry ***excluded, u32 *max_hops)
|
|
||||||
{
|
|
||||||
u16 num_excluded;
|
|
||||||
|
|
||||||
const u8 *cursor = p;
|
|
||||||
size_t plen = tal_count(p);
|
|
||||||
|
|
||||||
if (fromwire_u16(&cursor, &plen) != WIRE_GOSSIPD_GETROUTE_REQUEST)
|
|
||||||
return false;
|
|
||||||
/* Source defaults to "us" */
|
|
||||||
if (!fromwire_bool(&cursor, &plen))
|
|
||||||
*source = NULL;
|
|
||||||
else {
|
|
||||||
*source = tal(ctx, struct node_id);
|
|
||||||
fromwire_node_id(&cursor, &plen, *source);
|
|
||||||
}
|
|
||||||
fromwire_node_id(&cursor, &plen, destination);
|
|
||||||
*msatoshi = fromwire_amount_msat(&cursor, &plen);
|
|
||||||
*riskfactor_millionths = fromwire_u64(&cursor, &plen);
|
|
||||||
*final_cltv = fromwire_u32(&cursor, &plen);
|
|
||||||
*fuzz_millionths = fromwire_u64(&cursor, &plen);
|
|
||||||
num_excluded = fromwire_u16(&cursor, &plen);
|
|
||||||
// 2nd case excluded
|
|
||||||
*excluded = num_excluded ? tal_arr(ctx, struct exclude_entry *, num_excluded) : NULL;
|
|
||||||
for (size_t i = 0; i < num_excluded; i++)
|
|
||||||
(*excluded)[i] = fromwire_exclude_entry(*excluded, &cursor, &plen);
|
|
||||||
*max_hops = fromwire_u32(&cursor, &plen);
|
|
||||||
return cursor != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GETROUTE_REPLY */
|
|
||||||
u8 *towire_gossipd_getroute_reply(const tal_t *ctx, const struct route_hop **hops)
|
|
||||||
{
|
|
||||||
u16 num_hops = tal_count(hops);
|
|
||||||
u8 *p = tal_arr(ctx, u8, 0);
|
|
||||||
|
|
||||||
towire_u16(&p, WIRE_GOSSIPD_GETROUTE_REPLY);
|
|
||||||
towire_u16(&p, num_hops);
|
|
||||||
for (size_t i = 0; i < num_hops; i++)
|
|
||||||
towire_route_hop(&p, hops[i]);
|
|
||||||
|
|
||||||
return memcheck(p, tal_count(p));
|
|
||||||
}
|
|
||||||
bool fromwire_gossipd_getroute_reply(const tal_t *ctx, const void *p, struct route_hop ***hops)
|
|
||||||
{
|
|
||||||
u16 num_hops;
|
|
||||||
|
|
||||||
const u8 *cursor = p;
|
|
||||||
size_t plen = tal_count(p);
|
|
||||||
|
|
||||||
if (fromwire_u16(&cursor, &plen) != WIRE_GOSSIPD_GETROUTE_REPLY)
|
|
||||||
return false;
|
|
||||||
num_hops = fromwire_u16(&cursor, &plen);
|
|
||||||
// 2nd case hops
|
|
||||||
*hops = num_hops ? tal_arr(ctx, struct route_hop *, num_hops) : NULL;
|
|
||||||
for (size_t i = 0; i < num_hops; i++)
|
|
||||||
(*hops)[i] = fromwire_route_hop(*hops, &cursor, &plen);
|
|
||||||
return cursor != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GETCHANNELS_REQUEST */
|
|
||||||
u8 *towire_gossipd_getchannels_request(const tal_t *ctx, const struct short_channel_id *short_channel_id, const struct node_id *source, const struct short_channel_id *prev)
|
|
||||||
{
|
|
||||||
u8 *p = tal_arr(ctx, u8, 0);
|
|
||||||
|
|
||||||
towire_u16(&p, WIRE_GOSSIPD_GETCHANNELS_REQUEST);
|
|
||||||
if (!short_channel_id)
|
|
||||||
towire_bool(&p, false);
|
|
||||||
else {
|
|
||||||
towire_bool(&p, true);
|
|
||||||
towire_short_channel_id(&p, short_channel_id);
|
|
||||||
}
|
|
||||||
if (!source)
|
|
||||||
towire_bool(&p, false);
|
|
||||||
else {
|
|
||||||
towire_bool(&p, true);
|
|
||||||
towire_node_id(&p, source);
|
|
||||||
}
|
|
||||||
if (!prev)
|
|
||||||
towire_bool(&p, false);
|
|
||||||
else {
|
|
||||||
towire_bool(&p, true);
|
|
||||||
towire_short_channel_id(&p, prev);
|
|
||||||
}
|
|
||||||
|
|
||||||
return memcheck(p, tal_count(p));
|
|
||||||
}
|
|
||||||
bool fromwire_gossipd_getchannels_request(const tal_t *ctx, const void *p, struct short_channel_id **short_channel_id, struct node_id **source, struct short_channel_id **prev)
|
|
||||||
{
|
|
||||||
const u8 *cursor = p;
|
|
||||||
size_t plen = tal_count(p);
|
|
||||||
|
|
||||||
if (fromwire_u16(&cursor, &plen) != WIRE_GOSSIPD_GETCHANNELS_REQUEST)
|
|
||||||
return false;
|
|
||||||
if (!fromwire_bool(&cursor, &plen))
|
|
||||||
*short_channel_id = NULL;
|
|
||||||
else {
|
|
||||||
*short_channel_id = tal(ctx, struct short_channel_id);
|
|
||||||
fromwire_short_channel_id(&cursor, &plen, *short_channel_id);
|
|
||||||
}
|
|
||||||
if (!fromwire_bool(&cursor, &plen))
|
|
||||||
*source = NULL;
|
|
||||||
else {
|
|
||||||
*source = tal(ctx, struct node_id);
|
|
||||||
fromwire_node_id(&cursor, &plen, *source);
|
|
||||||
}
|
|
||||||
if (!fromwire_bool(&cursor, &plen))
|
|
||||||
*prev = NULL;
|
|
||||||
else {
|
|
||||||
*prev = tal(ctx, struct short_channel_id);
|
|
||||||
fromwire_short_channel_id(&cursor, &plen, *prev);
|
|
||||||
}
|
|
||||||
return cursor != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GETCHANNELS_REPLY */
|
|
||||||
u8 *towire_gossipd_getchannels_reply(const tal_t *ctx, bool complete, const struct gossip_getchannels_entry **nodes)
|
|
||||||
{
|
|
||||||
u32 num_channels = tal_count(nodes);
|
|
||||||
u8 *p = tal_arr(ctx, u8, 0);
|
|
||||||
|
|
||||||
towire_u16(&p, WIRE_GOSSIPD_GETCHANNELS_REPLY);
|
|
||||||
towire_bool(&p, complete);
|
|
||||||
towire_u32(&p, num_channels);
|
|
||||||
for (size_t i = 0; i < num_channels; i++)
|
|
||||||
towire_gossip_getchannels_entry(&p, nodes[i]);
|
|
||||||
|
|
||||||
return memcheck(p, tal_count(p));
|
|
||||||
}
|
|
||||||
bool fromwire_gossipd_getchannels_reply(const tal_t *ctx, const void *p, bool *complete, struct gossip_getchannels_entry ***nodes)
|
|
||||||
{
|
|
||||||
u32 num_channels;
|
|
||||||
|
|
||||||
const u8 *cursor = p;
|
|
||||||
size_t plen = tal_count(p);
|
|
||||||
|
|
||||||
if (fromwire_u16(&cursor, &plen) != WIRE_GOSSIPD_GETCHANNELS_REPLY)
|
|
||||||
return false;
|
|
||||||
*complete = fromwire_bool(&cursor, &plen);
|
|
||||||
num_channels = fromwire_u32(&cursor, &plen);
|
|
||||||
// 2nd case nodes
|
|
||||||
*nodes = num_channels ? tal_arr(ctx, struct gossip_getchannels_entry *, num_channels) : NULL;
|
|
||||||
for (size_t i = 0; i < num_channels; i++)
|
|
||||||
(*nodes)[i] = fromwire_gossip_getchannels_entry(*nodes, &cursor, &plen);
|
|
||||||
return cursor != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_PING */
|
/* WIRE: GOSSIPD_PING */
|
||||||
/* Ping/pong test. Waits for a reply if it expects one. */
|
/* Ping/pong test. Waits for a reply if it expects one. */
|
||||||
u8 *towire_gossipd_ping(const tal_t *ctx, const struct node_id *id, u16 num_pong_bytes, u16 len)
|
u8 *towire_gossipd_ping(const tal_t *ctx, const struct node_id *id, u16 num_pong_bytes, u16 len)
|
||||||
@ -742,79 +490,6 @@ bool fromwire_gossipd_dev_compact_store_reply(const void *p, bool *success)
|
|||||||
return cursor != NULL;
|
return cursor != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GET_INCOMING_CHANNELS */
|
|
||||||
/* master -> gossipd: get route_info for our incoming channels */
|
|
||||||
u8 *towire_gossipd_get_incoming_channels(const tal_t *ctx)
|
|
||||||
{
|
|
||||||
u8 *p = tal_arr(ctx, u8, 0);
|
|
||||||
|
|
||||||
towire_u16(&p, WIRE_GOSSIPD_GET_INCOMING_CHANNELS);
|
|
||||||
|
|
||||||
return memcheck(p, tal_count(p));
|
|
||||||
}
|
|
||||||
bool fromwire_gossipd_get_incoming_channels(const void *p)
|
|
||||||
{
|
|
||||||
const u8 *cursor = p;
|
|
||||||
size_t plen = tal_count(p);
|
|
||||||
|
|
||||||
if (fromwire_u16(&cursor, &plen) != WIRE_GOSSIPD_GET_INCOMING_CHANNELS)
|
|
||||||
return false;
|
|
||||||
return cursor != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GET_INCOMING_CHANNELS_REPLY */
|
|
||||||
/* gossipd -> master: here they are. */
|
|
||||||
u8 *towire_gossipd_get_incoming_channels_reply(const tal_t *ctx, const struct route_info *public_route_info, const bool *public_deadends, const struct route_info *private_route_info, const bool *private_deadends)
|
|
||||||
{
|
|
||||||
u16 num_public = tal_count(public_deadends);
|
|
||||||
u16 num_private = tal_count(private_deadends);
|
|
||||||
u8 *p = tal_arr(ctx, u8, 0);
|
|
||||||
|
|
||||||
towire_u16(&p, WIRE_GOSSIPD_GET_INCOMING_CHANNELS_REPLY);
|
|
||||||
towire_u16(&p, num_public);
|
|
||||||
for (size_t i = 0; i < num_public; i++)
|
|
||||||
towire_route_info(&p, public_route_info + i);
|
|
||||||
for (size_t i = 0; i < num_public; i++)
|
|
||||||
towire_bool(&p, public_deadends[i]);
|
|
||||||
towire_u16(&p, num_private);
|
|
||||||
for (size_t i = 0; i < num_private; i++)
|
|
||||||
towire_route_info(&p, private_route_info + i);
|
|
||||||
for (size_t i = 0; i < num_private; i++)
|
|
||||||
towire_bool(&p, private_deadends[i]);
|
|
||||||
|
|
||||||
return memcheck(p, tal_count(p));
|
|
||||||
}
|
|
||||||
bool fromwire_gossipd_get_incoming_channels_reply(const tal_t *ctx, const void *p, struct route_info **public_route_info, bool **public_deadends, struct route_info **private_route_info, bool **private_deadends)
|
|
||||||
{
|
|
||||||
u16 num_public;
|
|
||||||
u16 num_private;
|
|
||||||
|
|
||||||
const u8 *cursor = p;
|
|
||||||
size_t plen = tal_count(p);
|
|
||||||
|
|
||||||
if (fromwire_u16(&cursor, &plen) != WIRE_GOSSIPD_GET_INCOMING_CHANNELS_REPLY)
|
|
||||||
return false;
|
|
||||||
num_public = fromwire_u16(&cursor, &plen);
|
|
||||||
// 2nd case public_route_info
|
|
||||||
*public_route_info = num_public ? tal_arr(ctx, struct route_info, num_public) : NULL;
|
|
||||||
for (size_t i = 0; i < num_public; i++)
|
|
||||||
fromwire_route_info(&cursor, &plen, *public_route_info + i);
|
|
||||||
// 2nd case public_deadends
|
|
||||||
*public_deadends = num_public ? tal_arr(ctx, bool, num_public) : NULL;
|
|
||||||
for (size_t i = 0; i < num_public; i++)
|
|
||||||
(*public_deadends)[i] = fromwire_bool(&cursor, &plen);
|
|
||||||
num_private = fromwire_u16(&cursor, &plen);
|
|
||||||
// 2nd case private_route_info
|
|
||||||
*private_route_info = num_private ? tal_arr(ctx, struct route_info, num_private) : NULL;
|
|
||||||
for (size_t i = 0; i < num_private; i++)
|
|
||||||
fromwire_route_info(&cursor, &plen, *private_route_info + i);
|
|
||||||
// 2nd case private_deadends
|
|
||||||
*private_deadends = num_private ? tal_arr(ctx, bool, num_private) : NULL;
|
|
||||||
for (size_t i = 0; i < num_private; i++)
|
|
||||||
(*private_deadends)[i] = fromwire_bool(&cursor, &plen);
|
|
||||||
return cursor != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_NEW_BLOCKHEIGHT */
|
/* WIRE: GOSSIPD_NEW_BLOCKHEIGHT */
|
||||||
/* master -> gossipd: blockheight increased. */
|
/* master -> gossipd: blockheight increased. */
|
||||||
u8 *towire_gossipd_new_blockheight(const tal_t *ctx, u32 blockheight)
|
u8 *towire_gossipd_new_blockheight(const tal_t *ctx, u32 blockheight)
|
||||||
@ -1057,4 +732,4 @@ bool fromwire_gossipd_addgossip_reply(const tal_t *ctx, const void *p, wirestrin
|
|||||||
*err = fromwire_wirestring(ctx, &cursor, &plen);
|
*err = fromwire_wirestring(ctx, &cursor, &plen);
|
||||||
return cursor != NULL;
|
return cursor != NULL;
|
||||||
}
|
}
|
||||||
// SHA256STAMP:a0d7494995d7f95fb7df295bab9d865e18670f15243116a0aaa9b9548534b922
|
// SHA256STAMP:bc9045727cefbbe29118c8eae928972fe009a4d9d8c9e903f8b35f006973f462
|
||||||
|
52
gossipd/gossipd_wiregen.h
generated
52
gossipd/gossipd_wiregen.h
generated
@ -11,22 +11,12 @@
|
|||||||
#include <common/features.h>
|
#include <common/features.h>
|
||||||
#include <common/wireaddr.h>
|
#include <common/wireaddr.h>
|
||||||
#include <wire/onion_wire.h>
|
#include <wire/onion_wire.h>
|
||||||
#include <lightningd/gossip_msg.h>
|
|
||||||
#include <common/bolt11.h>
|
|
||||||
|
|
||||||
enum gossipd_wire {
|
enum gossipd_wire {
|
||||||
/* Initialize the gossip daemon. */
|
/* Initialize the gossip daemon. */
|
||||||
WIRE_GOSSIPD_INIT = 3000,
|
WIRE_GOSSIPD_INIT = 3000,
|
||||||
/* In developer mode */
|
/* In developer mode */
|
||||||
WIRE_GOSSIPD_DEV_SET_TIME = 3001,
|
WIRE_GOSSIPD_DEV_SET_TIME = 3001,
|
||||||
/* Pass JSON-RPC getnodes call through */
|
|
||||||
WIRE_GOSSIPD_GETNODES_REQUEST = 3005,
|
|
||||||
WIRE_GOSSIPD_GETNODES_REPLY = 3105,
|
|
||||||
/* Pass JSON-RPC getroute call through */
|
|
||||||
WIRE_GOSSIPD_GETROUTE_REQUEST = 3006,
|
|
||||||
WIRE_GOSSIPD_GETROUTE_REPLY = 3106,
|
|
||||||
WIRE_GOSSIPD_GETCHANNELS_REQUEST = 3007,
|
|
||||||
WIRE_GOSSIPD_GETCHANNELS_REPLY = 3107,
|
|
||||||
/* Ping/pong test. Waits for a reply if it expects one. */
|
/* Ping/pong test. Waits for a reply if it expects one. */
|
||||||
WIRE_GOSSIPD_PING = 3008,
|
WIRE_GOSSIPD_PING = 3008,
|
||||||
WIRE_GOSSIPD_PING_REPLY = 3108,
|
WIRE_GOSSIPD_PING_REPLY = 3108,
|
||||||
@ -52,10 +42,6 @@ enum gossipd_wire {
|
|||||||
WIRE_GOSSIPD_DEV_COMPACT_STORE = 3034,
|
WIRE_GOSSIPD_DEV_COMPACT_STORE = 3034,
|
||||||
/* gossipd -> master: ok */
|
/* gossipd -> master: ok */
|
||||||
WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY = 3134,
|
WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY = 3134,
|
||||||
/* master -> gossipd: get route_info for our incoming channels */
|
|
||||||
WIRE_GOSSIPD_GET_INCOMING_CHANNELS = 3025,
|
|
||||||
/* gossipd -> master: here they are. */
|
|
||||||
WIRE_GOSSIPD_GET_INCOMING_CHANNELS_REPLY = 3125,
|
|
||||||
/* master -> gossipd: blockheight increased. */
|
/* master -> gossipd: blockheight increased. */
|
||||||
WIRE_GOSSIPD_NEW_BLOCKHEIGHT = 3026,
|
WIRE_GOSSIPD_NEW_BLOCKHEIGHT = 3026,
|
||||||
/* Tell lightningd we got a onion message (for us */
|
/* Tell lightningd we got a onion message (for us */
|
||||||
@ -91,32 +77,6 @@ bool fromwire_gossipd_init(const tal_t *ctx, const void *p, const struct chainpa
|
|||||||
u8 *towire_gossipd_dev_set_time(const tal_t *ctx, u32 dev_gossip_time);
|
u8 *towire_gossipd_dev_set_time(const tal_t *ctx, u32 dev_gossip_time);
|
||||||
bool fromwire_gossipd_dev_set_time(const void *p, u32 *dev_gossip_time);
|
bool fromwire_gossipd_dev_set_time(const void *p, u32 *dev_gossip_time);
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GETNODES_REQUEST */
|
|
||||||
/* Pass JSON-RPC getnodes call through */
|
|
||||||
u8 *towire_gossipd_getnodes_request(const tal_t *ctx, const struct node_id *id);
|
|
||||||
bool fromwire_gossipd_getnodes_request(const tal_t *ctx, const void *p, struct node_id **id);
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GETNODES_REPLY */
|
|
||||||
u8 *towire_gossipd_getnodes_reply(const tal_t *ctx, const struct gossip_getnodes_entry **nodes);
|
|
||||||
bool fromwire_gossipd_getnodes_reply(const tal_t *ctx, const void *p, struct gossip_getnodes_entry ***nodes);
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GETROUTE_REQUEST */
|
|
||||||
/* Pass JSON-RPC getroute call through */
|
|
||||||
u8 *towire_gossipd_getroute_request(const tal_t *ctx, const struct node_id *source, const struct node_id *destination, struct amount_msat msatoshi, u64 riskfactor_millionths, u32 final_cltv, u64 fuzz_millionths, const struct exclude_entry **excluded, u32 max_hops);
|
|
||||||
bool fromwire_gossipd_getroute_request(const tal_t *ctx, const void *p, struct node_id **source, struct node_id *destination, struct amount_msat *msatoshi, u64 *riskfactor_millionths, u32 *final_cltv, u64 *fuzz_millionths, struct exclude_entry ***excluded, u32 *max_hops);
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GETROUTE_REPLY */
|
|
||||||
u8 *towire_gossipd_getroute_reply(const tal_t *ctx, const struct route_hop **hops);
|
|
||||||
bool fromwire_gossipd_getroute_reply(const tal_t *ctx, const void *p, struct route_hop ***hops);
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GETCHANNELS_REQUEST */
|
|
||||||
u8 *towire_gossipd_getchannels_request(const tal_t *ctx, const struct short_channel_id *short_channel_id, const struct node_id *source, const struct short_channel_id *prev);
|
|
||||||
bool fromwire_gossipd_getchannels_request(const tal_t *ctx, const void *p, struct short_channel_id **short_channel_id, struct node_id **source, struct short_channel_id **prev);
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GETCHANNELS_REPLY */
|
|
||||||
u8 *towire_gossipd_getchannels_reply(const tal_t *ctx, bool complete, const struct gossip_getchannels_entry **nodes);
|
|
||||||
bool fromwire_gossipd_getchannels_reply(const tal_t *ctx, const void *p, bool *complete, struct gossip_getchannels_entry ***nodes);
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_PING */
|
/* WIRE: GOSSIPD_PING */
|
||||||
/* Ping/pong test. Waits for a reply if it expects one. */
|
/* Ping/pong test. Waits for a reply if it expects one. */
|
||||||
u8 *towire_gossipd_ping(const tal_t *ctx, const struct node_id *id, u16 num_pong_bytes, u16 len);
|
u8 *towire_gossipd_ping(const tal_t *ctx, const struct node_id *id, u16 num_pong_bytes, u16 len);
|
||||||
@ -184,16 +144,6 @@ bool fromwire_gossipd_dev_compact_store(const void *p);
|
|||||||
u8 *towire_gossipd_dev_compact_store_reply(const tal_t *ctx, bool success);
|
u8 *towire_gossipd_dev_compact_store_reply(const tal_t *ctx, bool success);
|
||||||
bool fromwire_gossipd_dev_compact_store_reply(const void *p, bool *success);
|
bool fromwire_gossipd_dev_compact_store_reply(const void *p, bool *success);
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GET_INCOMING_CHANNELS */
|
|
||||||
/* master -> gossipd: get route_info for our incoming channels */
|
|
||||||
u8 *towire_gossipd_get_incoming_channels(const tal_t *ctx);
|
|
||||||
bool fromwire_gossipd_get_incoming_channels(const void *p);
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_GET_INCOMING_CHANNELS_REPLY */
|
|
||||||
/* gossipd -> master: here they are. */
|
|
||||||
u8 *towire_gossipd_get_incoming_channels_reply(const tal_t *ctx, const struct route_info *public_route_info, const bool *public_deadends, const struct route_info *private_route_info, const bool *private_deadends);
|
|
||||||
bool fromwire_gossipd_get_incoming_channels_reply(const tal_t *ctx, const void *p, struct route_info **public_route_info, bool **public_deadends, struct route_info **private_route_info, bool **private_deadends);
|
|
||||||
|
|
||||||
/* WIRE: GOSSIPD_NEW_BLOCKHEIGHT */
|
/* WIRE: GOSSIPD_NEW_BLOCKHEIGHT */
|
||||||
/* master -> gossipd: blockheight increased. */
|
/* master -> gossipd: blockheight increased. */
|
||||||
u8 *towire_gossipd_new_blockheight(const tal_t *ctx, u32 blockheight);
|
u8 *towire_gossipd_new_blockheight(const tal_t *ctx, u32 blockheight);
|
||||||
@ -225,4 +175,4 @@ bool fromwire_gossipd_addgossip_reply(const tal_t *ctx, const void *p, wirestrin
|
|||||||
|
|
||||||
|
|
||||||
#endif /* LIGHTNING_GOSSIPD_GOSSIPD_WIREGEN_H */
|
#endif /* LIGHTNING_GOSSIPD_GOSSIPD_WIREGEN_H */
|
||||||
// SHA256STAMP:a0d7494995d7f95fb7df295bab9d865e18670f15243116a0aaa9b9548534b922
|
// SHA256STAMP:bc9045727cefbbe29118c8eae928972fe009a4d9d8c9e903f8b35f006973f462
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -20,34 +20,11 @@ struct peer;
|
|||||||
struct routing_state;
|
struct routing_state;
|
||||||
|
|
||||||
struct half_chan {
|
struct half_chan {
|
||||||
/* millisatoshi. */
|
|
||||||
u32 base_fee;
|
|
||||||
/* millionths */
|
|
||||||
u32 proportional_fee;
|
|
||||||
|
|
||||||
/* Delay for HTLC in blocks.*/
|
|
||||||
u32 delay;
|
|
||||||
|
|
||||||
/* Timestamp and index into store file */
|
/* Timestamp and index into store file */
|
||||||
struct broadcastable bcast;
|
struct broadcastable bcast;
|
||||||
|
|
||||||
/* Flags as specified by the `channel_update`s, among other
|
|
||||||
* things indicated direction wrt the `channel_id` */
|
|
||||||
u8 channel_flags;
|
|
||||||
|
|
||||||
/* Flags as specified by the `channel_update`s, indicates
|
|
||||||
* optional fields. */
|
|
||||||
u8 message_flags;
|
|
||||||
|
|
||||||
/* Token bucket */
|
/* Token bucket */
|
||||||
u8 tokens;
|
u8 tokens;
|
||||||
|
|
||||||
/* Feature cache for parent chan: squeezed in here where it would
|
|
||||||
* otherwise simply be padding. */
|
|
||||||
u8 any_features;
|
|
||||||
|
|
||||||
/* Minimum and maximum number of msatoshi in an HTLC */
|
|
||||||
struct amount_msat htlc_minimum, htlc_maximum;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chan {
|
struct chan {
|
||||||
@ -96,11 +73,6 @@ static inline bool is_halfchan_defined(const struct half_chan *hc)
|
|||||||
return hc->bcast.index != 0;
|
return hc->bcast.index != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_halfchan_enabled(const struct half_chan *hc)
|
|
||||||
{
|
|
||||||
return is_halfchan_defined(hc) && !(hc->channel_flags & ROUTING_FLAGS_DISABLED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Container for per-node channel pointers. Better cache performance
|
/* Container for per-node channel pointers. Better cache performance
|
||||||
* than uintmap, and we don't need ordering. */
|
* than uintmap, and we don't need ordering. */
|
||||||
static inline const struct short_channel_id *chan_map_scid(const struct chan *c)
|
static inline const struct short_channel_id *chan_map_scid(const struct chan *c)
|
||||||
@ -152,22 +124,11 @@ struct node {
|
|||||||
/* Token bucket */
|
/* Token bucket */
|
||||||
u8 tokens;
|
u8 tokens;
|
||||||
|
|
||||||
/* route_hop_style */
|
|
||||||
enum route_hop_style hop_style;
|
|
||||||
|
|
||||||
/* Channels connecting us to other nodes */
|
/* Channels connecting us to other nodes */
|
||||||
union {
|
union {
|
||||||
struct chan_map map;
|
struct chan_map map;
|
||||||
struct chan *arr[NUM_IMMEDIATE_CHANS+1];
|
struct chan *arr[NUM_IMMEDIATE_CHANS+1];
|
||||||
} chans;
|
} chans;
|
||||||
|
|
||||||
/* Temporary data for routefinding. */
|
|
||||||
struct {
|
|
||||||
/* Total to get to here from target. */
|
|
||||||
struct amount_msat total;
|
|
||||||
/* Total risk premium of this route. */
|
|
||||||
struct amount_msat risk;
|
|
||||||
} dijkstra;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct node_id *node_map_keyof_node(const struct node *n);
|
const struct node_id *node_map_keyof_node(const struct node *n);
|
||||||
@ -319,19 +280,6 @@ get_channel(const struct routing_state *rstate,
|
|||||||
return uintmap_get(&rstate->chanmap, scid->u64);
|
return uintmap_get(&rstate->chanmap, scid->u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum exclude_entry_type {
|
|
||||||
EXCLUDE_CHANNEL = 1,
|
|
||||||
EXCLUDE_NODE = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
struct exclude_entry {
|
|
||||||
enum exclude_entry_type type;
|
|
||||||
union {
|
|
||||||
struct short_channel_id_dir chan_id;
|
|
||||||
struct node_id node_id;
|
|
||||||
} u;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct routing_state *new_routing_state(const tal_t *ctx,
|
struct routing_state *new_routing_state(const tal_t *ctx,
|
||||||
const struct node_id *local_id,
|
const struct node_id *local_id,
|
||||||
struct list_head *peers,
|
struct list_head *peers,
|
||||||
@ -350,8 +298,7 @@ struct chan *new_chan(struct routing_state *rstate,
|
|||||||
const struct short_channel_id *scid,
|
const struct short_channel_id *scid,
|
||||||
const struct node_id *id1,
|
const struct node_id *id1,
|
||||||
const struct node_id *id2,
|
const struct node_id *id2,
|
||||||
struct amount_sat sat,
|
struct amount_sat sat);
|
||||||
const u8 *features);
|
|
||||||
|
|
||||||
/* Handlers for incoming messages */
|
/* Handlers for incoming messages */
|
||||||
|
|
||||||
@ -400,17 +347,6 @@ u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node,
|
|||||||
struct node *get_node(struct routing_state *rstate,
|
struct node *get_node(struct routing_state *rstate,
|
||||||
const struct node_id *id);
|
const struct node_id *id);
|
||||||
|
|
||||||
/* Compute a route to a destination, for a given amount and riskfactor. */
|
|
||||||
struct route_hop **get_route(const tal_t *ctx, struct routing_state *rstate,
|
|
||||||
const struct node_id *source,
|
|
||||||
const struct node_id *destination,
|
|
||||||
const struct amount_msat msat, double riskfactor,
|
|
||||||
u32 final_cltv,
|
|
||||||
double fuzz,
|
|
||||||
u64 seed,
|
|
||||||
struct exclude_entry **excluded,
|
|
||||||
u32 max_hops);
|
|
||||||
|
|
||||||
void route_prune(struct routing_state *rstate);
|
void route_prune(struct routing_state *rstate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,14 +134,10 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
|
|||||||
switch (t) {
|
switch (t) {
|
||||||
/* These are messages we send, not them. */
|
/* These are messages we send, not them. */
|
||||||
case WIRE_GOSSIPD_INIT:
|
case WIRE_GOSSIPD_INIT:
|
||||||
case WIRE_GOSSIPD_GETNODES_REQUEST:
|
|
||||||
case WIRE_GOSSIPD_GETROUTE_REQUEST:
|
|
||||||
case WIRE_GOSSIPD_GETCHANNELS_REQUEST:
|
|
||||||
case WIRE_GOSSIPD_PING:
|
case WIRE_GOSSIPD_PING:
|
||||||
case WIRE_GOSSIPD_GET_STRIPPED_CUPDATE:
|
case WIRE_GOSSIPD_GET_STRIPPED_CUPDATE:
|
||||||
case WIRE_GOSSIPD_GET_TXOUT_REPLY:
|
case WIRE_GOSSIPD_GET_TXOUT_REPLY:
|
||||||
case WIRE_GOSSIPD_OUTPOINT_SPENT:
|
case WIRE_GOSSIPD_OUTPOINT_SPENT:
|
||||||
case WIRE_GOSSIPD_GET_INCOMING_CHANNELS:
|
|
||||||
case WIRE_GOSSIPD_DEV_SET_MAX_SCIDS_ENCODE_SIZE:
|
case WIRE_GOSSIPD_DEV_SET_MAX_SCIDS_ENCODE_SIZE:
|
||||||
case WIRE_GOSSIPD_DEV_SUPPRESS:
|
case WIRE_GOSSIPD_DEV_SUPPRESS:
|
||||||
case WIRE_GOSSIPD_LOCAL_CHANNEL_CLOSE:
|
case WIRE_GOSSIPD_LOCAL_CHANNEL_CLOSE:
|
||||||
@ -152,10 +148,6 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
|
|||||||
case WIRE_GOSSIPD_SEND_ONIONMSG:
|
case WIRE_GOSSIPD_SEND_ONIONMSG:
|
||||||
case WIRE_GOSSIPD_ADDGOSSIP:
|
case WIRE_GOSSIPD_ADDGOSSIP:
|
||||||
/* This is a reply, so never gets through to here. */
|
/* This is a reply, so never gets through to here. */
|
||||||
case WIRE_GOSSIPD_GETNODES_REPLY:
|
|
||||||
case WIRE_GOSSIPD_GETROUTE_REPLY:
|
|
||||||
case WIRE_GOSSIPD_GETCHANNELS_REPLY:
|
|
||||||
case WIRE_GOSSIPD_GET_INCOMING_CHANNELS_REPLY:
|
|
||||||
case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY:
|
case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY:
|
||||||
case WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY:
|
case WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY:
|
||||||
case WIRE_GOSSIPD_GET_STRIPPED_CUPDATE_REPLY:
|
case WIRE_GOSSIPD_GET_STRIPPED_CUPDATE_REPLY:
|
||||||
@ -235,347 +227,6 @@ void gossipd_notify_spend(struct lightningd *ld,
|
|||||||
subd_send_msg(ld->gossip, msg);
|
subd_send_msg(ld->gossip, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_getnodes_reply(struct subd *gossip UNUSED, const u8 *reply,
|
|
||||||
const int *fds UNUSED,
|
|
||||||
struct command *cmd)
|
|
||||||
{
|
|
||||||
struct gossip_getnodes_entry **nodes;
|
|
||||||
struct json_stream *response;
|
|
||||||
size_t i, j;
|
|
||||||
|
|
||||||
if (!fromwire_gossipd_getnodes_reply(reply, reply, &nodes)) {
|
|
||||||
was_pending(command_fail(cmd, LIGHTNINGD,
|
|
||||||
"Malformed gossip_getnodes response"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
|
||||||
json_array_start(response, "nodes");
|
|
||||||
|
|
||||||
for (i = 0; i < tal_count(nodes); i++) {
|
|
||||||
struct json_escape *esc;
|
|
||||||
|
|
||||||
json_object_start(response, NULL);
|
|
||||||
json_add_node_id(response, "nodeid", &nodes[i]->nodeid);
|
|
||||||
if (nodes[i]->last_timestamp < 0) {
|
|
||||||
json_object_end(response);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
esc = json_escape(NULL,
|
|
||||||
take(tal_strndup(NULL,
|
|
||||||
(const char *)nodes[i]->alias,
|
|
||||||
ARRAY_SIZE(nodes[i]->alias))));
|
|
||||||
json_add_escaped_string(response, "alias", take(esc));
|
|
||||||
json_add_hex(response, "color",
|
|
||||||
nodes[i]->color, ARRAY_SIZE(nodes[i]->color));
|
|
||||||
json_add_u64(response, "last_timestamp",
|
|
||||||
nodes[i]->last_timestamp);
|
|
||||||
json_add_hex_talarr(response, "features", nodes[i]->features);
|
|
||||||
json_array_start(response, "addresses");
|
|
||||||
for (j=0; j<tal_count(nodes[i]->addresses); j++) {
|
|
||||||
json_add_address(response, NULL, &nodes[i]->addresses[j]);
|
|
||||||
}
|
|
||||||
json_array_end(response);
|
|
||||||
json_object_end(response);
|
|
||||||
}
|
|
||||||
json_array_end(response);
|
|
||||||
was_pending(command_success(cmd, response));
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct command_result *json_listnodes(struct command *cmd,
|
|
||||||
const char *buffer,
|
|
||||||
const jsmntok_t *obj UNNEEDED,
|
|
||||||
const jsmntok_t *params)
|
|
||||||
{
|
|
||||||
u8 *req;
|
|
||||||
struct node_id *id;
|
|
||||||
|
|
||||||
if (!param(cmd, buffer, params,
|
|
||||||
p_opt("id", param_node_id, &id),
|
|
||||||
NULL))
|
|
||||||
return command_param_failed();
|
|
||||||
|
|
||||||
req = towire_gossipd_getnodes_request(cmd, id);
|
|
||||||
subd_req(cmd, cmd->ld->gossip, req, -1, 0, json_getnodes_reply, cmd);
|
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct json_command listnodes_command = {
|
|
||||||
"listnodesold",
|
|
||||||
"network",
|
|
||||||
json_listnodes,
|
|
||||||
"Show node {id} (or all, if no {id}), in our local network view"
|
|
||||||
};
|
|
||||||
AUTODATA(json_command, &listnodes_command);
|
|
||||||
|
|
||||||
static void json_add_route_hop_style(struct json_stream *response,
|
|
||||||
const char *fieldname,
|
|
||||||
enum route_hop_style style)
|
|
||||||
{
|
|
||||||
switch (style) {
|
|
||||||
case ROUTE_HOP_LEGACY:
|
|
||||||
json_add_string(response, fieldname, "legacy");
|
|
||||||
return;
|
|
||||||
case ROUTE_HOP_TLV:
|
|
||||||
json_add_string(response, fieldname, "tlv");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
fatal("Unknown route_hop_style %u", style);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output a route hop */
|
|
||||||
static void json_add_route_hop(struct json_stream *r, char const *n,
|
|
||||||
const struct route_hop *h)
|
|
||||||
{
|
|
||||||
/* Imitate what getroute/sendpay use */
|
|
||||||
json_object_start(r, n);
|
|
||||||
json_add_node_id(r, "id", &h->node_id);
|
|
||||||
json_add_short_channel_id(r, "channel", &h->scid);
|
|
||||||
json_add_num(r, "direction", h->direction);
|
|
||||||
json_add_amount_msat_compat(r, h->amount, "msatoshi", "amount_msat");
|
|
||||||
json_add_num(r, "delay", h->delay);
|
|
||||||
json_add_route_hop_style(r, "style", h->style);
|
|
||||||
json_object_end(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output a route */
|
|
||||||
static void json_add_route(struct json_stream *r, char const *n,
|
|
||||||
struct route_hop **hops, size_t hops_len)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
json_array_start(r, n);
|
|
||||||
for (i = 0; i < hops_len; ++i) {
|
|
||||||
json_add_route_hop(r, NULL, hops[i]);
|
|
||||||
}
|
|
||||||
json_array_end(r);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void json_getroute_reply(struct subd *gossip UNUSED, const u8 *reply, const int *fds UNUSED,
|
|
||||||
struct command *cmd)
|
|
||||||
{
|
|
||||||
struct json_stream *response;
|
|
||||||
struct route_hop **hops;
|
|
||||||
|
|
||||||
fromwire_gossipd_getroute_reply(reply, reply, &hops);
|
|
||||||
|
|
||||||
if (tal_count(hops) == 0) {
|
|
||||||
was_pending(command_fail(cmd, PAY_ROUTE_NOT_FOUND,
|
|
||||||
"Could not find a route"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
response = json_stream_success(cmd);
|
|
||||||
json_add_route(response, "route", hops, tal_count(hops));
|
|
||||||
was_pending(command_success(cmd, response));
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct command_result *json_getroute(struct command *cmd,
|
|
||||||
const char *buffer,
|
|
||||||
const jsmntok_t *obj UNNEEDED,
|
|
||||||
const jsmntok_t *params)
|
|
||||||
{
|
|
||||||
struct lightningd *ld = cmd->ld;
|
|
||||||
struct node_id *destination;
|
|
||||||
struct node_id *source;
|
|
||||||
const jsmntok_t *excludetok;
|
|
||||||
struct amount_msat *msat;
|
|
||||||
u32 *cltv;
|
|
||||||
/* risk factor 12.345% -> riskfactor_millionths = 12345000 */
|
|
||||||
u64 *riskfactor_millionths;
|
|
||||||
const struct exclude_entry **excluded;
|
|
||||||
u32 *max_hops;
|
|
||||||
|
|
||||||
/* Higher fuzz means that some high-fee paths can be discounted
|
|
||||||
* for an even larger value, increasing the scope for route
|
|
||||||
* randomization (the higher-fee paths become more likely to
|
|
||||||
* be selected) at the cost of increasing the probability of
|
|
||||||
* selecting the higher-fee paths. */
|
|
||||||
u64 *fuzz_millionths; /* fuzz 12.345% -> fuzz_millionths = 12345000 */
|
|
||||||
|
|
||||||
if (!param(
|
|
||||||
cmd, buffer, params, p_req("id", param_node_id, &destination),
|
|
||||||
p_req("msatoshi", param_msat, &msat),
|
|
||||||
p_req("riskfactor", param_millionths, &riskfactor_millionths),
|
|
||||||
p_opt_def("cltv", param_number, &cltv, 9),
|
|
||||||
p_opt("fromid", param_node_id, &source),
|
|
||||||
p_opt_def("fuzzpercent", param_millionths, &fuzz_millionths,
|
|
||||||
5000000),
|
|
||||||
p_opt("exclude", param_array, &excludetok),
|
|
||||||
p_opt_def("maxhops", param_number, &max_hops, ROUTING_MAX_HOPS),
|
|
||||||
NULL))
|
|
||||||
return command_param_failed();
|
|
||||||
|
|
||||||
/* Convert from percentage */
|
|
||||||
*fuzz_millionths /= 100;
|
|
||||||
|
|
||||||
if (excludetok) {
|
|
||||||
const jsmntok_t *t;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
excluded = tal_arr(cmd, const struct exclude_entry *, 0);
|
|
||||||
|
|
||||||
json_for_each_arr(i, t, excludetok) {
|
|
||||||
struct exclude_entry *entry = tal(excluded, struct exclude_entry);
|
|
||||||
struct short_channel_id_dir *chan_id = tal(tmpctx, struct short_channel_id_dir);
|
|
||||||
if (!short_channel_id_dir_from_str(buffer + t->start,
|
|
||||||
t->end - t->start,
|
|
||||||
chan_id)) {
|
|
||||||
struct node_id *node_id = tal(tmpctx, struct node_id);
|
|
||||||
|
|
||||||
if (!json_to_node_id(buffer, t, node_id))
|
|
||||||
return command_fail_badparam(cmd, "exclude",
|
|
||||||
buffer, t,
|
|
||||||
"should be short_channel_id or node_id");
|
|
||||||
|
|
||||||
entry->type = EXCLUDE_NODE;
|
|
||||||
entry->u.node_id = *node_id;
|
|
||||||
} else {
|
|
||||||
entry->type = EXCLUDE_CHANNEL;
|
|
||||||
entry->u.chan_id = *chan_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
tal_arr_expand(&excluded, entry);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
excluded = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
u8 *req = towire_gossipd_getroute_request(
|
|
||||||
cmd, source, destination, *msat, *riskfactor_millionths, *cltv,
|
|
||||||
*fuzz_millionths, excluded, *max_hops);
|
|
||||||
subd_req(ld->gossip, ld->gossip, req, -1, 0, json_getroute_reply, cmd);
|
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct json_command getroute_command = {
|
|
||||||
"getrouteold",
|
|
||||||
"channels",
|
|
||||||
json_getroute,
|
|
||||||
"Show route to {id} for {msatoshi}, using {riskfactor} and optional {cltv} (default 9). "
|
|
||||||
"If specified search from {fromid} otherwise use this node as source. "
|
|
||||||
"Randomize the route with up to {fuzzpercent} (default 5.0). "
|
|
||||||
"{exclude} an array of short-channel-id/direction (e.g. [ '564334x877x1/0', '564195x1292x0/1' ]) "
|
|
||||||
"or node-id from consideration. "
|
|
||||||
"Set the {maxhops} the route can take (default 20)."
|
|
||||||
};
|
|
||||||
AUTODATA(json_command, &getroute_command);
|
|
||||||
|
|
||||||
static void json_add_halfchan(struct json_stream *response,
|
|
||||||
const struct gossip_getchannels_entry *e,
|
|
||||||
int idx)
|
|
||||||
{
|
|
||||||
const struct gossip_halfchannel_entry *he = e->e[idx];
|
|
||||||
if (!he)
|
|
||||||
return;
|
|
||||||
|
|
||||||
json_object_start(response, NULL);
|
|
||||||
json_add_node_id(response, "source", &e->node[idx]);
|
|
||||||
json_add_node_id(response, "destination", &e->node[!idx]);
|
|
||||||
json_add_short_channel_id(response, "short_channel_id",
|
|
||||||
&e->short_channel_id);
|
|
||||||
json_add_bool(response, "public", e->public);
|
|
||||||
json_add_amount_sat_compat(response, e->sat,
|
|
||||||
"satoshis", "amount_msat");
|
|
||||||
json_add_num(response, "message_flags", he->message_flags);
|
|
||||||
json_add_num(response, "channel_flags", he->channel_flags);
|
|
||||||
json_add_bool(response, "active",
|
|
||||||
!(he->channel_flags & ROUTING_FLAGS_DISABLED)
|
|
||||||
&& !e->local_disabled);
|
|
||||||
json_add_num(response, "last_update", he->last_update_timestamp);
|
|
||||||
json_add_num(response, "base_fee_millisatoshi", he->base_fee_msat);
|
|
||||||
json_add_num(response, "fee_per_millionth", he->fee_per_millionth);
|
|
||||||
json_add_num(response, "delay", he->delay);
|
|
||||||
json_add_amount_msat_only(response, "htlc_minimum_msat", he->min);
|
|
||||||
json_add_amount_msat_only(response, "htlc_maximum_msat", he->max);
|
|
||||||
json_add_hex_talarr(response, "features", e->features);
|
|
||||||
json_object_end(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct listchannels_info {
|
|
||||||
struct command *cmd;
|
|
||||||
struct json_stream *response;
|
|
||||||
struct short_channel_id *id;
|
|
||||||
struct node_id *source;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Called upon receiving a getchannels_reply from `gossipd` */
|
|
||||||
static void json_listchannels_reply(struct subd *gossip UNUSED, const u8 *reply,
|
|
||||||
const int *fds UNUSED,
|
|
||||||
struct listchannels_info *linfo)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
struct gossip_getchannels_entry **entries;
|
|
||||||
bool complete;
|
|
||||||
|
|
||||||
if (!fromwire_gossipd_getchannels_reply(reply, reply,
|
|
||||||
&complete, &entries)) {
|
|
||||||
/* Shouldn't happen: just end json stream. */
|
|
||||||
log_broken(linfo->cmd->ld->log, "Invalid reply from gossipd");
|
|
||||||
was_pending(command_raw_complete(linfo->cmd, linfo->response));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < tal_count(entries); i++) {
|
|
||||||
json_add_halfchan(linfo->response, entries[i], 0);
|
|
||||||
json_add_halfchan(linfo->response, entries[i], 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* More coming? Ask from this point on.. */
|
|
||||||
if (!complete) {
|
|
||||||
u8 *req;
|
|
||||||
assert(tal_count(entries) != 0);
|
|
||||||
req = towire_gossipd_getchannels_request(linfo->cmd,
|
|
||||||
linfo->id,
|
|
||||||
linfo->source,
|
|
||||||
&entries[i-1]
|
|
||||||
->short_channel_id);
|
|
||||||
subd_req(linfo->cmd->ld->gossip, linfo->cmd->ld->gossip,
|
|
||||||
req, -1, 0, json_listchannels_reply, linfo);
|
|
||||||
} else {
|
|
||||||
json_array_end(linfo->response);
|
|
||||||
was_pending(command_success(linfo->cmd, linfo->response));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct command_result *json_listchannels(struct command *cmd,
|
|
||||||
const char *buffer,
|
|
||||||
const jsmntok_t *obj UNNEEDED,
|
|
||||||
const jsmntok_t *params)
|
|
||||||
{
|
|
||||||
u8 *req;
|
|
||||||
struct listchannels_info *linfo = tal(cmd, struct listchannels_info);
|
|
||||||
|
|
||||||
linfo->cmd = cmd;
|
|
||||||
if (!param(cmd, buffer, params,
|
|
||||||
p_opt("short_channel_id", param_short_channel_id, &linfo->id),
|
|
||||||
p_opt("source", param_node_id, &linfo->source),
|
|
||||||
NULL))
|
|
||||||
return command_param_failed();
|
|
||||||
|
|
||||||
if (linfo->id && linfo->source)
|
|
||||||
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
|
||||||
"Cannot specify both source and short_channel_id");
|
|
||||||
|
|
||||||
/* Start JSON response, then we stream. */
|
|
||||||
linfo->response = json_stream_success(cmd);
|
|
||||||
json_array_start(linfo->response, "channels");
|
|
||||||
|
|
||||||
req = towire_gossipd_getchannels_request(cmd, linfo->id, linfo->source,
|
|
||||||
NULL);
|
|
||||||
subd_req(cmd->ld->gossip, cmd->ld->gossip,
|
|
||||||
req, -1, 0, json_listchannels_reply, linfo);
|
|
||||||
|
|
||||||
return command_still_pending(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct json_command listchannels_command = {
|
|
||||||
"listchannelsold",
|
|
||||||
"channels",
|
|
||||||
json_listchannels,
|
|
||||||
"Show channel {short_channel_id} or {source} (or all known channels, if not specified)"
|
|
||||||
};
|
|
||||||
AUTODATA(json_command, &listchannels_command);
|
|
||||||
|
|
||||||
/* Called upon receiving a addgossip_reply from `gossipd` */
|
/* Called upon receiving a addgossip_reply from `gossipd` */
|
||||||
static void json_addgossip_reply(struct subd *gossip UNUSED, const u8 *reply,
|
static void json_addgossip_reply(struct subd *gossip UNUSED, const u8 *reply,
|
||||||
const int *fds UNUSED,
|
const int *fds UNUSED,
|
||||||
|
@ -194,32 +194,3 @@ void towire_gossip_getchannels_entry(u8 **pptr,
|
|||||||
} else
|
} else
|
||||||
towire_bool(pptr, false);
|
towire_bool(pptr, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct exclude_entry *fromwire_exclude_entry(const tal_t *ctx,
|
|
||||||
const u8 **pptr, size_t *max)
|
|
||||||
{
|
|
||||||
struct exclude_entry *entry = tal(ctx, struct exclude_entry);
|
|
||||||
entry->type = fromwire_u8(pptr, max);
|
|
||||||
switch (entry->type) {
|
|
||||||
case EXCLUDE_CHANNEL:
|
|
||||||
fromwire_short_channel_id_dir(pptr, max, &entry->u.chan_id);
|
|
||||||
return entry;
|
|
||||||
case EXCLUDE_NODE:
|
|
||||||
fromwire_node_id(pptr, max, &entry->u.node_id);
|
|
||||||
return entry;
|
|
||||||
default:
|
|
||||||
return fromwire_fail(pptr, max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void towire_exclude_entry(u8 **pptr, const struct exclude_entry *entry)
|
|
||||||
{
|
|
||||||
assert(entry->type == EXCLUDE_CHANNEL ||
|
|
||||||
entry->type == EXCLUDE_NODE);
|
|
||||||
|
|
||||||
towire_u8(pptr, entry->type);
|
|
||||||
if (entry->type == EXCLUDE_CHANNEL)
|
|
||||||
towire_short_channel_id_dir(pptr, &entry->u.chan_id);
|
|
||||||
else
|
|
||||||
towire_node_id(pptr, &entry->u.node_id);
|
|
||||||
}
|
|
||||||
|
@ -54,9 +54,4 @@ fromwire_gossip_getchannels_entry(const tal_t *ctx,
|
|||||||
void towire_gossip_getchannels_entry(
|
void towire_gossip_getchannels_entry(
|
||||||
u8 **pptr, const struct gossip_getchannels_entry *entry);
|
u8 **pptr, const struct gossip_getchannels_entry *entry);
|
||||||
|
|
||||||
struct exclude_entry *
|
|
||||||
fromwire_exclude_entry(const tal_t *ctx,
|
|
||||||
const u8 **pptr, size_t *max);
|
|
||||||
void towire_exclude_entry(u8 **pptr, const struct exclude_entry *entry);
|
|
||||||
|
|
||||||
#endif /* LIGHTNING_LIGHTNINGD_GOSSIP_MSG_H */
|
#endif /* LIGHTNING_LIGHTNINGD_GOSSIP_MSG_H */
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include <common/onion.h>
|
#include <common/onion.h>
|
||||||
#include <common/onionreply.h>
|
#include <common/onionreply.h>
|
||||||
#include <common/param.h>
|
#include <common/param.h>
|
||||||
|
#include <common/route.h>
|
||||||
#include <common/timeout.h>
|
#include <common/timeout.h>
|
||||||
#include <gossipd/gossipd_wiregen.h>
|
#include <gossipd/gossipd_wiregen.h>
|
||||||
#include <lightningd/chaintopology.h>
|
#include <lightningd/chaintopology.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user