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:
Rusty Russell 2021-06-15 06:37:39 +09:30
parent 8810ce7241
commit 7e7ab4cb3b
11 changed files with 41 additions and 2187 deletions

View File

@ -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, &timestamp,
&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);
} }

View File

@ -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:

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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);
/** /**

View File

@ -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,

View File

@ -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);
}

View File

@ -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 */

View File

@ -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>