gossip: Replay the entire store on init instead of when idle

This now works because we no longer call out to masterd or bitcoind to verify
the channels. It's also rather quick and silent so we can just process all
stored messages until we're done.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
Christian Decker 2018-03-25 18:45:13 +02:00 committed by Rusty Russell
parent c4ea79cc5c
commit 44e23b3773
3 changed files with 16 additions and 35 deletions

View File

@ -1522,24 +1522,6 @@ static void setup_listeners(struct daemon *daemon, u16 portnum)
portnum);
}
/**
* Callback function to be called whenever the master connection is idle
*/
static bool master_conn_idle(struct io_conn *conn UNUSED,
struct daemon_conn *dc)
{
const u8 *msg;
struct daemon *daemon = container_of(dc, struct daemon, master);
msg = gossip_store_read_next(tmpctx, daemon->rstate, daemon->rstate->store);
if (msg) {
handle_gossip_msg(daemon, msg, false);
return true;
} else {
return false;
}
}
/* Parse an incoming gossip init message and assign config variables
* to the daemon.
*/
@ -1562,14 +1544,16 @@ static struct io_plan *gossip_init(struct daemon_conn *master,
daemon->rstate = new_routing_state(daemon, &chain_hash, &daemon->id,
update_channel_interval * 2);
master->msg_queue_cleared_cb = master_conn_idle;
setup_listeners(daemon, port);
new_reltimer(&daemon->timers, daemon,
time_from_sec(daemon->rstate->prune_timeout/4),
gossip_refresh_network, daemon);
/* Load stored gossip messages */
while (gossip_store_read_next(daemon->rstate, daemon->rstate->store)) {
}
return daemon_conn_read_next(master->conn, master);
}

View File

@ -82,8 +82,8 @@ void gossip_store_add_node_announcement(struct gossip_store *gs,
tal_free(msg);
}
const u8 *gossip_store_read_next(const tal_t *ctx, struct routing_state *rstate,
struct gossip_store *gs)
bool gossip_store_read_next(struct routing_state *rstate,
struct gossip_store *gs)
{
beint32_t belen;
u32 msglen;
@ -98,11 +98,11 @@ const u8 *gossip_store_read_next(const tal_t *ctx, struct routing_state *rstate,
/* Can we read one message? */
if (pread(gs->fd, &belen, sizeof(belen), gs->read_pos) != sizeof(belen)) {
gs->read_pos = -1;
return NULL;
return false;
}
msglen = be32_to_cpu(belen);
msg = tal_arr(ctx, u8, msglen);
msg = tal_arr(gs, u8, msglen);
if (!pread(gs->fd, msg, msglen, gs->read_pos + sizeof(belen))) {
status_trace("Short read from gossip-store, expected lenght %d",
@ -113,7 +113,8 @@ const u8 *gossip_store_read_next(const tal_t *ctx, struct routing_state *rstate,
gs->write_pos = gs->read_pos;
gs->read_pos = -1;
ftruncate(gs->fd, gs->write_pos);
return NULL;
tal_free(msg);
return false;
}
gs->read_pos += sizeof(belen) + msglen;
@ -122,17 +123,13 @@ const u8 *gossip_store_read_next(const tal_t *ctx, struct routing_state *rstate,
if (type == WIRE_GOSSIP_STORE_CHANNEL_ANNOUNCEMENT) {
fromwire_gossip_store_channel_announcement(msg, msg, &gossip_msg, &satoshis);
routing_add_channel_announcement(rstate, gossip_msg, satoshis);
/* No harm in returning it, it'll get discarded as a duplicate */
return gossip_msg;
} else if(type == WIRE_GOSSIP_STORE_CHANNEL_UPDATE) {
fromwire_gossip_store_channel_update(msg, msg, &gossip_msg);
routing_add_channel_update(rstate, gossip_msg);
return gossip_msg;
} else if(type == WIRE_GOSSIP_STORE_NODE_ANNOUNCEMENT) {
fromwire_gossip_store_node_announcement(msg, msg, &gossip_msg);
routing_add_node_announcement(rstate, gossip_msg);
return gossip_msg;
}
return msg;
tal_free(msg);
return true;
}

View File

@ -29,11 +29,11 @@ void gossip_store_append(struct gossip_store *gs, const u8 *msg);
*
* @param ctx The context to allocate the message from
* @param gs The `gossip_store` to read from
* @return The gossip message allocated from `ctx`, `NULL` if no more messages are
* available.
* @return whether a message was read from the store. False means that all
* messages have been processed.
*/
const u8 *gossip_store_read_next(const tal_t *ctx, struct routing_state *rstate,
struct gossip_store *gs);
bool gossip_store_read_next(struct routing_state *rstate,
struct gossip_store *gs);
/**
* Store a channel_announcement with all its extra data