Browse Source

gossipd: remove some fields from struct chan.

The txout_script field is unused; the local_disable only applies to
the handful of local channels, so move that into a hash table.

MCP results from 5 runs, min-max(mean +/- stddev):
	store_load_msec:39207-45089(41374.6+/-2.2e+03)
	vsz_kb:1202316
	store_rewrite_sec:15.090000-16.790000(15.654+/-0.63)
	listnodes_sec:1.290000-3.790000(1.938+/-0.93)
	listchannels_sec:30.190000-32.120000(31.31+/-0.69)
	routing_sec:28.220000-31.340000(29.314+/-1.2)
	peer_write_all_sec:66.830000-76.850000(71.976+/-3.6)

MCP notable changes from previous patch (>1 stddev):
	-store_load_msec:35107-37944(36686+/-1e+03)
	+store_load_msec:39207-45089(41374.6+/-2.2e+03)
	-vsz_kb:1218036
	+vsz_kb:1202316
	-listchannels_sec:28.510000-30.270000(29.6+/-0.6)
	+listchannels_sec:30.190000-32.120000(31.31+/-0.69)

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
pr-2587
Rusty Russell 6 years ago
committed by neil saitug
parent
commit
aeb72a05e3
  1. 32
      gossipd/gossipd.c
  2. 17
      gossipd/routing.c
  3. 29
      gossipd/routing.h

32
gossipd/gossipd.c

@ -180,7 +180,7 @@ static void peer_disable_channels(struct daemon *daemon, struct node *node)
for (c = first_chan(node, &i); c; c = next_chan(node, &i)) {
if (node_id_eq(&other_node(node, c)->id, &daemon->id))
c->local_disabled = true;
local_disable_chan(daemon->rstate, c);
}
}
@ -1371,19 +1371,21 @@ static void maybe_update_local_channel(struct daemon *daemon,
struct chan *chan, int direction)
{
const struct half_chan *hc = &chan->half[direction];
bool local_disabled;
/* Don't generate a channel_update for an uninitialized channel. */
if (!hc->channel_update)
return;
/* Nothing to update? */
local_disabled = is_chan_local_disabled(daemon->rstate, chan);
/*~ Note the inversions here on both sides, which is cheap conversion to
* boolean for the RHS! */
if (!chan->local_disabled == !(hc->channel_flags & ROUTING_FLAGS_DISABLED))
if (!local_disabled == !(hc->channel_flags & ROUTING_FLAGS_DISABLED))
return;
update_local_channel(daemon, chan, direction,
chan->local_disabled,
local_disabled,
hc->delay,
hc->htlc_minimum,
hc->base_fee,
@ -1555,7 +1557,11 @@ static bool handle_local_channel_update(struct peer *peer, const u8 *msg)
/* Normal case: just toggle local_disabled, and generate broadcast in
* maybe_update_local_channel when/if someone asks about it. */
chan->local_disabled = disable;
if (disable)
local_disable_chan(peer->daemon->rstate, chan);
else
local_enable_chan(peer->daemon->rstate, chan);
return true;
}
@ -1833,7 +1839,7 @@ static void gossip_send_keepalive_update(struct daemon *daemon,
* local_disabled state */
update_local_channel(daemon, chan,
hc->channel_flags & ROUTING_FLAGS_DIRECTION,
chan->local_disabled,
is_chan_local_disabled(daemon->rstate, chan),
hc->delay,
hc->htlc_minimum,
hc->base_fee,
@ -1912,7 +1918,7 @@ static void gossip_disable_local_channels(struct daemon *daemon)
return;
for (c = first_chan(local_node, &i); c; c = next_chan(local_node, &i))
c->local_disabled = true;
local_disable_chan(daemon->rstate, c);
}
/*~ Parse init message from lightningd: starts the daemon properly. */
@ -2044,7 +2050,8 @@ static struct gossip_halfchannel_entry *hc_entry(const tal_t *ctx,
}
/*~ Marshal (possibly) both channel directions into entries. */
static void append_channel(const struct gossip_getchannels_entry ***entries,
static void append_channel(struct routing_state *rstate,
const struct gossip_getchannels_entry ***entries,
const struct chan *chan,
const struct node_id *srcfilter)
{
@ -2053,7 +2060,7 @@ static void append_channel(const struct gossip_getchannels_entry ***entries,
e->node[0] = chan->nodes[0]->id;
e->node[1] = chan->nodes[1]->id;
e->sat = chan->sat;
e->local_disabled = chan->local_disabled;
e->local_disabled = is_chan_local_disabled(rstate, chan);
e->public = is_chan_public(chan);
e->short_channel_id = chan->scid;
if (!srcfilter || node_id_eq(&e->node[0], srcfilter))
@ -2092,7 +2099,7 @@ static struct io_plan *getchannels_req(struct io_conn *conn,
if (scid) {
chan = get_channel(daemon->rstate, scid);
if (chan)
append_channel(&entries, chan, NULL);
append_channel(daemon->rstate, &entries, chan, NULL);
} else if (source) {
struct node *s = get_node(daemon->rstate, source);
if (s) {
@ -2100,7 +2107,8 @@ static struct io_plan *getchannels_req(struct io_conn *conn,
struct chan *c;
for (c = first_chan(s, &i); c; c = next_chan(s, &i)) {
append_channel(&entries, c, source);
append_channel(daemon->rstate,
&entries, c, source);
}
}
} else {
@ -2111,7 +2119,7 @@ static struct io_plan *getchannels_req(struct io_conn *conn,
for (chan = uintmap_first(&daemon->rstate->chanmap, &idx);
chan;
chan = uintmap_after(&daemon->rstate->chanmap, &idx)) {
append_channel(&entries, chan, NULL);
append_channel(daemon->rstate, &entries, chan, NULL);
}
}
@ -2758,7 +2766,7 @@ static struct io_plan *handle_local_channel_close(struct io_conn *conn,
chan = get_channel(rstate, &scid);
if (chan)
chan->local_disabled = true;
local_disable_chan(rstate, chan);
return daemon_conn_read_next(conn, daemon->master);
}

17
gossipd/routing.c

@ -194,6 +194,7 @@ struct routing_state *new_routing_state(const tal_t *ctx,
list_head_init(&rstate->pending_cannouncement);
uintmap_init(&rstate->chanmap);
uintmap_init(&rstate->unupdated_chanmap);
chan_map_init(&rstate->local_disabled_map);
uintmap_init(&rstate->txout_failures);
rstate->pending_node_map = tal(ctx, struct pending_node_map);
@ -374,6 +375,9 @@ static void destroy_chan(struct chan *chan, struct routing_state *rstate)
broadcast_del(rstate->broadcasts, &chan->half[1].bcast);
uintmap_del(&rstate->chanmap, chan->scid.u64);
/* Remove from local_disabled_map if it's there. */
chan_map_del(&rstate->local_disabled_map, chan);
}
static void init_half_chan(struct routing_state *rstate,
@ -423,10 +427,8 @@ struct chan *new_chan(struct routing_state *rstate,
chan->scid = *scid;
chan->nodes[n1idx] = n1;
chan->nodes[!n1idx] = n2;
chan->txout_script = NULL;
broadcastable_init(&chan->bcast);
chan->sat = satoshis;
chan->local_disabled = false;
add_chan(n2, chan);
add_chan(n1, chan);
@ -579,10 +581,11 @@ static void bfg_one_edge(struct node *node,
}
/* Determine if the given half_chan is routable */
static bool hc_is_routable(const struct chan *chan, int idx)
static bool hc_is_routable(struct routing_state *rstate,
const struct chan *chan, int idx)
{
return !chan->local_disabled
&& is_halfchan_enabled(&chan->half[idx]);
return is_halfchan_enabled(&chan->half[idx])
&& !is_chan_local_disabled(rstate, chan);
}
/* riskfactor is already scaled to per-block amount */
@ -655,9 +658,9 @@ find_route(const tal_t *ctx, struct routing_state *rstate,
struct short_channel_id,
&c->scid));
if (!hc_is_routable(chan, idx)) {
if (!hc_is_routable(rstate, chan, idx)) {
SUPERVERBOSE("...unroutable (local_disabled = %i, is_halfchan_enabled = %i, unroutable_until = %i",
chan->local_disabled,
is_chan_local_disabled(rstate, chan),
is_halfchan_enabled(&chan->half[idx]),
chan->half[idx].unroutable_until >= now);
continue;

29
gossipd/routing.h

@ -42,7 +42,6 @@ struct half_chan {
struct chan {
struct short_channel_id scid;
u8 *txout_script;
/*
* half[0]->src == nodes[0] half[0]->dst == nodes[1]
@ -55,9 +54,6 @@ struct chan {
/* Timestamp and index into store file */
struct broadcastable bcast;
/* Disabled locally (due to peer disconnect) */
bool local_disabled;
struct amount_sat sat;
};
@ -201,6 +197,9 @@ struct routing_state {
* checks if we get another announcement for the same scid. */
UINTMAP(bool) txout_failures;
/* A map of (local) disabled channels by short_channel_ids */
struct chan_map local_disabled_map;
#if DEVELOPER
/* Override local time for gossip messages */
struct timeabs *gossip_time;
@ -361,6 +360,28 @@ void memleak_remove_routing_tables(struct htable *memtable,
*/
struct timeabs gossip_time_now(const struct routing_state *rstate);
/* Because we can have millions of channels, and we only want a local_disable
* flag on ones connected to us, we keep a separate hashtable for that flag.
*/
static inline bool is_chan_local_disabled(struct routing_state *rstate,
const struct chan *chan)
{
return chan_map_get(&rstate->local_disabled_map, &chan->scid) != NULL;
}
static inline void local_disable_chan(struct routing_state *rstate,
const struct chan *chan)
{
if (!is_chan_local_disabled(rstate, chan))
chan_map_add(&rstate->local_disabled_map, chan);
}
static inline void local_enable_chan(struct routing_state *rstate,
const struct chan *chan)
{
chan_map_del(&rstate->local_disabled_map, chan);
}
/* Helper to convert on-wire addresses format to wireaddrs array */
struct wireaddr *read_addresses(const tal_t *ctx, const u8 *ser);
#endif /* LIGHTNING_GOSSIPD_ROUTING_H */

Loading…
Cancel
Save