gossipd: don't keep channel_updates in memory.

This requires some trickiness when we want to re-add unannounced channels
to the store after compaction, so we extract a common "copy_message" to
transfer from old store to new.

MCP results from 5 runs, min-max(mean +/- stddev):
	store_load_msec:36034-37853(37109.8+/-5.9e+02)
	vsz_kb:577456
	store_rewrite_sec:12.490000-13.250000(12.862+/-0.27)
	listnodes_sec:1.250000-1.480000(1.364+/-0.09)
	listchannels_sec:30.820000-31.480000(31.068+/-0.24)
	routing_sec:26.940000-27.990000(27.616+/-0.39)
	peer_write_all_sec:65.690000-68.600000(66.698+/-0.99)

MCP notable changes from previous patch (>1 stddev):
	-vsz_kb:1202316
	+vsz_kb:577456

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2019-04-11 14:46:30 +09:30
committed by neil saitug
parent 0370ed2eca
commit fdb42c3170
7 changed files with 92 additions and 53 deletions

View File

@@ -386,8 +386,6 @@ static void init_half_chan(struct routing_state *rstate,
{
struct half_chan *c = &chan->half[channel_idx];
c->channel_update = NULL;
/* Set the channel direction */
c->channel_flags = channel_idx;
// TODO: wireup message_flags
@@ -971,11 +969,17 @@ bool routing_add_channel_announcement(struct routing_state *rstate,
* add fresh ones. But if we're loading off disk right now, we can't
* do that. */
if (chan && index == 0) {
/* Steal any private updates */
private_updates[0]
= tal_steal(NULL, chan->half[0].channel_update);
private_updates[1]
= tal_steal(NULL, chan->half[1].channel_update);
/* Reload any private updates */
if (chan->half[0].bcast.index)
private_updates[0]
= gossip_store_get(NULL,
rstate->broadcasts->gs,
chan->half[0].bcast.index);
if (chan->half[1].bcast.index)
private_updates[1]
= gossip_store_get(NULL,
rstate->broadcasts->gs,
chan->half[1].bcast.index);
}
/* Pretend it didn't exist, for the moment. */
@@ -1330,6 +1334,10 @@ bool routing_add_channel_update(struct routing_state *rstate,
if (taken(update))
tal_steal(tmpctx, update);
/* In case it's free in a failure path */
if (taken(update))
tal_steal(tmpctx, update);
if (!fromwire_channel_update(update, &signature, &chain_hash,
&short_channel_id, &timestamp,
&message_flags, &channel_flags,
@@ -1388,18 +1396,6 @@ bool routing_add_channel_update(struct routing_state *rstate,
/* Discard older updates */
hc = &chan->half[direction];
if (is_halfchan_defined(hc) && timestamp <= hc->bcast.timestamp) {
/* They're not supposed to do this! */
if (timestamp == hc->bcast.timestamp
&& !memeq(hc->channel_update, tal_count(hc->channel_update),
update, tal_count(update))) {
status_debug("Bad gossip repeated timestamp for %s(%u): %s then %s",
type_to_string(tmpctx,
struct short_channel_id,
&short_channel_id),
channel_flags,
tal_hex(tmpctx, hc->channel_update),
tal_hex(tmpctx, update));
}
SUPERVERBOSE("Ignoring outdated update.");
/* Ignoring != failing */
return true;
@@ -1416,15 +1412,9 @@ bool routing_add_channel_update(struct routing_state *rstate,
message_flags, channel_flags,
timestamp, htlc_minimum, htlc_maximum);
/* Replace any old one. */
tal_free(chan->half[direction].channel_update);
/* Safe even if was never added */
broadcast_del(rstate->broadcasts, &chan->half[direction].bcast);
chan->half[direction].channel_update
= tal_dup_arr(chan, u8, update, tal_count(update), 0);
/* BOLT #7:
* - MUST consider the `timestamp` of the `channel_announcement` to be
* the `timestamp` of a corresponding `channel_update`.
@@ -1444,7 +1434,7 @@ bool routing_add_channel_update(struct routing_state *rstate,
assert(is_local_channel(rstate, chan));
if (!index) {
hc->bcast.index = gossip_store_add(rstate->broadcasts->gs,
hc->channel_update);
update);
} else
hc->bcast.index = index;
return true;
@@ -1454,7 +1444,7 @@ bool routing_add_channel_update(struct routing_state *rstate,
chan->half[direction].bcast.index = index;
insert_broadcast(&rstate->broadcasts,
chan->half[direction].channel_update,
update,
&chan->half[direction].bcast);
if (uc) {