Browse Source

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>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
f083a699e2
  1. 29
      gossipd/gossip.c
  2. 9
      gossipd/gossip_wire.csv
  3. 34
      lightningd/gossip_control.c
  4. 1
      lightningd/gossip_control.h
  5. 7
      lightningd/lightningd.c
  6. 3
      lightningd/test/run-find_my_path.c

29
gossipd/gossip.c

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

9
gossipd/gossip_wire.csv

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

Can't render this file because it has a wrong number of fields in line 6.

34
lightningd/gossip_control.c

@ -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);
}
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 init done */ /* Wait for activate done */
io_loop(NULL, NULL); io_loop(NULL, NULL);
} }

1
lightningd/gossip_control.h

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

7
lightningd/lightningd.c

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

3
lightningd/test/run-find_my_path.c

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

Loading…
Cancel
Save