gossipd: separate init and activate.

This means gossipd is live and we can tell it things, but it won't
receive incoming connections.  The split also means that the main daemon
continues (eg. loading peers from db) while gossipd is loading from the store,
potentially speeding startup.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-04-30 11:38:15 +09:30 committed by Christian Decker
parent 61317859f8
commit f083a699e2
6 changed files with 58 additions and 25 deletions

View file

@ -1625,12 +1625,11 @@ static struct io_plan *gossip_init(struct daemon_conn *master,
const u8 *msg) const u8 *msg)
{ {
struct bitcoin_blkid chain_hash; struct bitcoin_blkid chain_hash;
u16 port;
u32 update_channel_interval; u32 update_channel_interval;
if (!fromwire_gossipctl_init( if (!fromwire_gossipctl_init(
daemon, msg, &daemon->broadcast_interval, &chain_hash, daemon, msg, &daemon->broadcast_interval, &chain_hash,
&daemon->id, &port, &daemon->globalfeatures, &daemon->id, &daemon->globalfeatures,
&daemon->localfeatures, &daemon->wireaddrs, daemon->rgb, &daemon->localfeatures, &daemon->wireaddrs, daemon->rgb,
daemon->alias, &update_channel_interval, &daemon->no_reconnect)) { daemon->alias, &update_channel_interval, &daemon->no_reconnect)) {
master_badmsg(WIRE_GOSSIPCTL_INIT, msg); master_badmsg(WIRE_GOSSIPCTL_INIT, msg);
@ -1639,18 +1638,31 @@ static struct io_plan *gossip_init(struct daemon_conn *master,
daemon->rstate = new_routing_state(daemon, &chain_hash, &daemon->id, daemon->rstate = new_routing_state(daemon, &chain_hash, &daemon->id,
update_channel_interval * 2); update_channel_interval * 2);
setup_listeners(daemon, port); /* Load stored gossip messages */
gossip_store_load(daemon->rstate, daemon->rstate->store);
new_reltimer(&daemon->timers, daemon, new_reltimer(&daemon->timers, daemon,
time_from_sec(daemon->rstate->prune_timeout/4), time_from_sec(daemon->rstate->prune_timeout/4),
gossip_refresh_network, daemon); gossip_refresh_network, daemon);
/* Load stored gossip messages */ return daemon_conn_read_next(master->conn, master);
gossip_store_load(daemon->rstate, daemon->rstate->store); }
static struct io_plan *gossip_activate(struct daemon_conn *master,
struct daemon *daemon,
const u8 *msg)
{
u16 port;
if (!fromwire_gossipctl_activate(msg, &port))
master_badmsg(WIRE_GOSSIPCTL_ACTIVATE, msg);
setup_listeners(daemon, port);
/* OK, we're ready! */ /* OK, we're ready! */
daemon_conn_send(&daemon->master, daemon_conn_send(&daemon->master,
take(towire_gossipctl_init_reply(NULL))); take(towire_gossipctl_activate_reply(NULL)));
return daemon_conn_read_next(master->conn, master); return daemon_conn_read_next(master->conn, master);
} }
@ -2271,6 +2283,9 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
case WIRE_GOSSIPCTL_INIT: case WIRE_GOSSIPCTL_INIT:
return gossip_init(master, daemon, master->msg_in); return gossip_init(master, daemon, master->msg_in);
case WIRE_GOSSIPCTL_ACTIVATE:
return gossip_activate(master, daemon, master->msg_in);
case WIRE_GOSSIPCTL_RELEASE_PEER: case WIRE_GOSSIPCTL_RELEASE_PEER:
return release_peer(conn, daemon, master->msg_in); return release_peer(conn, daemon, master->msg_in);
@ -2326,7 +2341,7 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
return handle_outpoint_spent(conn, daemon, master->msg_in); return handle_outpoint_spent(conn, daemon, master->msg_in);
/* We send these, we don't receive them */ /* We send these, we don't receive them */
case WIRE_GOSSIPCTL_INIT_REPLY: case WIRE_GOSSIPCTL_ACTIVATE_REPLY:
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY: case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL: case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL:
case WIRE_GOSSIP_GETNODES_REPLY: case WIRE_GOSSIP_GETNODES_REPLY:

View file

@ -7,8 +7,6 @@ gossipctl_init,3000
gossipctl_init,,broadcast_interval,u32 gossipctl_init,,broadcast_interval,u32
gossipctl_init,,chain_hash,struct bitcoin_blkid gossipctl_init,,chain_hash,struct bitcoin_blkid
gossipctl_init,,id,struct pubkey gossipctl_init,,id,struct pubkey
# If non-zero, port to listen on.
gossipctl_init,,port,u16
gossipctl_init,,gflen,u16 gossipctl_init,,gflen,u16
gossipctl_init,,gfeatures,gflen*u8 gossipctl_init,,gfeatures,gflen*u8
gossipctl_init,,lflen,u16 gossipctl_init,,lflen,u16
@ -21,8 +19,13 @@ gossipctl_init,,update_channel_interval,u32
# DEVELOPER only # DEVELOPER only
gossipctl_init,,no_reconnect,bool gossipctl_init,,no_reconnect,bool
# Activate the gossip daemon, so others can connect.
gossipctl_activate,3025
# If non-zero, port to listen on.
gossipctl_activate,,port,u16
# Gossipd->master, I am ready. # Gossipd->master, I am ready.
gossipctl_init_reply,3100 gossipctl_activate_reply,3125
# Master -> gossipd: Optional hint for where to find peer. # Master -> gossipd: Optional hint for where to find peer.
gossipctl_peer_addrhint,3014 gossipctl_peer_addrhint,3014

1 #include <common/cryptomsg.h>
7 gossipctl_init,,chain_hash,struct bitcoin_blkid
8 gossipctl_init,,id,struct pubkey
9 # If non-zero, port to listen on. gossipctl_init,,gflen,u16
gossipctl_init,,port,u16
gossipctl_init,,gflen,u16
10 gossipctl_init,,gfeatures,gflen*u8
11 gossipctl_init,,lflen,u16
12 gossipctl_init,,lfeatures,lflen*u8
19 gossipctl_init,,no_reconnect,bool
20 # Gossipd->master, I am ready. # Activate the gossip daemon, so others can connect.
21 gossipctl_init_reply,3100 gossipctl_activate,3025
22 # If non-zero, port to listen on.
23 gossipctl_activate,,port,u16
24 # Gossipd->master, I am ready.
25 gossipctl_activate_reply,3125
26 # Master -> gossipd: Optional hint for where to find peer.
27 # Master -> gossipd: Optional hint for where to find peer. gossipctl_peer_addrhint,3014
28 gossipctl_peer_addrhint,3014 gossipctl_peer_addrhint,,id,struct pubkey
29 gossipctl_peer_addrhint,,id,struct pubkey gossipctl_peer_addrhint,,addr,struct wireaddr
30 gossipctl_peer_addrhint,,addr,struct wireaddr # Master -> gossipd: connect to a peer.
31 # Master -> gossipd: connect to a peer. gossipctl_connect_to_peer,3001

View file

@ -118,6 +118,7 @@ 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_GOSSIPCTL_INIT: case WIRE_GOSSIPCTL_INIT:
case WIRE_GOSSIPCTL_ACTIVATE:
case WIRE_GOSSIP_GETNODES_REQUEST: case WIRE_GOSSIP_GETNODES_REQUEST:
case WIRE_GOSSIP_GETROUTE_REQUEST: case WIRE_GOSSIP_GETROUTE_REQUEST:
case WIRE_GOSSIP_GETCHANNELS_REQUEST: case WIRE_GOSSIP_GETCHANNELS_REQUEST:
@ -139,7 +140,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
case WIRE_GOSSIPCTL_PEER_IMPORTANT: case WIRE_GOSSIPCTL_PEER_IMPORTANT:
case WIRE_GOSSIPCTL_PEER_DISCONNECTED: case WIRE_GOSSIPCTL_PEER_DISCONNECTED:
/* This is a reply, so never gets through to here. */ /* This is a reply, so never gets through to here. */
case WIRE_GOSSIPCTL_INIT_REPLY: case WIRE_GOSSIPCTL_ACTIVATE_REPLY:
case WIRE_GOSSIP_GET_UPDATE_REPLY: case WIRE_GOSSIP_GET_UPDATE_REPLY:
case WIRE_GOSSIP_GETNODES_REPLY: case WIRE_GOSSIP_GETNODES_REPLY:
case WIRE_GOSSIP_GETROUTE_REPLY: case WIRE_GOSSIP_GETROUTE_REPLY:
@ -175,15 +176,6 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
return 0; return 0;
} }
static void gossip_init_done(struct subd *gossip UNUSED,
const u8 *reply UNUSED,
const int *fds UNUSED,
void *unused UNUSED)
{
/* Break out of loop, so we can begin */
io_break(gossip);
}
/* Create the `gossipd` subdaemon and send the initialization /* Create the `gossipd` subdaemon and send the initialization
* message */ * message */
void gossip_init(struct lightningd *ld) void gossip_init(struct lightningd *ld)
@ -217,13 +209,29 @@ void gossip_init(struct lightningd *ld)
msg = towire_gossipctl_init( msg = towire_gossipctl_init(
tmpctx, ld->config.broadcast_interval, tmpctx, ld->config.broadcast_interval,
&get_chainparams(ld)->genesis_blockhash, &ld->id, ld->portnum, &get_chainparams(ld)->genesis_blockhash, &ld->id,
get_offered_global_features(tmpctx), get_offered_global_features(tmpctx),
get_offered_local_features(tmpctx), ld->wireaddrs, ld->rgb, get_offered_local_features(tmpctx), ld->wireaddrs, ld->rgb,
ld->alias, ld->config.channel_update_interval, no_reconnect); ld->alias, ld->config.channel_update_interval, no_reconnect);
subd_req(ld->gossip, ld->gossip, msg, -1, 0, gossip_init_done, NULL); subd_send_msg(ld->gossip, msg);
}
/* Wait for init done */ static void gossip_activate_done(struct subd *gossip UNUSED,
const u8 *reply UNUSED,
const int *fds UNUSED,
void *unused UNUSED)
{
/* Break out of loop, so we can begin */
io_break(gossip);
}
void gossip_activate(struct lightningd *ld)
{
const u8 *msg = towire_gossipctl_activate(NULL, ld->portnum);
subd_req(ld->gossip, ld->gossip, take(msg), -1, 0,
gossip_activate_done, NULL);
/* Wait for activate done */
io_loop(NULL, NULL); io_loop(NULL, NULL);
} }

View file

@ -8,6 +8,7 @@
struct lightningd; struct lightningd;
void gossip_init(struct lightningd *ld); void gossip_init(struct lightningd *ld);
void gossip_activate(struct lightningd *ld);
void gossipd_notify_spend(struct lightningd *ld, void gossipd_notify_spend(struct lightningd *ld,
const struct short_channel_id *scid); const struct short_channel_id *scid);

View file

@ -328,6 +328,9 @@ int main(int argc, char *argv[])
/* Now we know our ID, we can set our color/alias if not already. */ /* Now we know our ID, we can set our color/alias if not already. */
setup_color_and_alias(ld); setup_color_and_alias(ld);
/* Set up gossip daemon. */
gossip_init(ld);
/* Everything is within a transaction. */ /* Everything is within a transaction. */
db_begin_transaction(ld->wallet->db); db_begin_transaction(ld->wallet->db);
@ -391,9 +394,9 @@ int main(int argc, char *argv[])
ld->config.poll_time, ld->config.poll_time,
blockheight); blockheight);
/* Set up gossip daemon. Needs to be after the initialization of /* Activate gossip daemon. Needs to be after the initialization of
* chaintopology, otherwise we may be asking for uninitialized data. */ * chaintopology, otherwise we may be asking for uninitialized data. */
gossip_init(ld); gossip_activate(ld);
/* Replay transactions for all running onchainds */ /* Replay transactions for all running onchainds */
onchaind_replay_channels(ld); onchaind_replay_channels(ld);

View file

@ -42,6 +42,9 @@ void fatal(const char *fmt UNNEEDED, ...)
/* Generated stub for free_htlcs */ /* Generated stub for free_htlcs */
void free_htlcs(struct lightningd *ld UNNEEDED, const struct channel *channel UNNEEDED) void free_htlcs(struct lightningd *ld UNNEEDED, const struct channel *channel UNNEEDED)
{ fprintf(stderr, "free_htlcs called!\n"); abort(); } { fprintf(stderr, "free_htlcs called!\n"); abort(); }
/* Generated stub for gossip_activate */
void gossip_activate(struct lightningd *ld UNNEEDED)
{ fprintf(stderr, "gossip_activate called!\n"); abort(); }
/* Generated stub for gossip_init */ /* Generated stub for gossip_init */
void gossip_init(struct lightningd *ld UNNEEDED) void gossip_init(struct lightningd *ld UNNEEDED)
{ fprintf(stderr, "gossip_init called!\n"); abort(); } { fprintf(stderr, "gossip_init called!\n"); abort(); }