diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index eea5fd3d6904..d13ba5e4652c 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -1135,6 +1135,9 @@ static struct io_plan *gossip_init(struct io_conn *conn, daemon->connectd = daemon_conn_new(daemon, CONNECTD_FD, connectd_req, NULL, daemon); + /* OK, we are ready. */ + daemon_conn_send(daemon->master, + take(towire_gossipd_init_reply(NULL))); return daemon_conn_read_next(conn, daemon->master); } @@ -1507,6 +1510,7 @@ static struct io_plan *recv_req(struct io_conn *conn, return onionmsg_req(conn, daemon, msg); /* We send these, we don't receive them */ case WIRE_GOSSIPD_PING_REPLY: + case WIRE_GOSSIPD_INIT_REPLY: case WIRE_GOSSIPD_GET_STRIPPED_CUPDATE_REPLY: case WIRE_GOSSIPD_GET_TXOUT: case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY: diff --git a/gossipd/gossipd_wire.csv b/gossipd/gossipd_wire.csv index bb51590e2803..2dbd2b2245d7 100644 --- a/gossipd/gossipd_wire.csv +++ b/gossipd/gossipd_wire.csv @@ -16,6 +16,8 @@ msgdata,gossipd_init,dev_gossip_time,?u32, msgdata,gossipd_init,dev_fast_gossip,bool, msgdata,gossipd_init,dev_fast_gossip_prune,bool, +msgtype,gossipd_init_reply,3100 + # In developer mode, we can mess with time. msgtype,gossipd_dev_set_time,3001 msgdata,gossipd_dev_set_time,dev_gossip_time,u32, diff --git a/gossipd/gossipd_wiregen.c b/gossipd/gossipd_wiregen.c index e779e960192f..b5f6a2b328e0 100644 --- a/gossipd/gossipd_wiregen.c +++ b/gossipd/gossipd_wiregen.c @@ -21,6 +21,7 @@ const char *gossipd_wire_name(int e) switch ((enum gossipd_wire)e) { case WIRE_GOSSIPD_INIT: return "WIRE_GOSSIPD_INIT"; + case WIRE_GOSSIPD_INIT_REPLY: return "WIRE_GOSSIPD_INIT_REPLY"; case WIRE_GOSSIPD_DEV_SET_TIME: return "WIRE_GOSSIPD_DEV_SET_TIME"; case WIRE_GOSSIPD_PING: return "WIRE_GOSSIPD_PING"; case WIRE_GOSSIPD_PING_REPLY: return "WIRE_GOSSIPD_PING_REPLY"; @@ -52,6 +53,7 @@ bool gossipd_wire_is_defined(u16 type) { switch ((enum gossipd_wire)type) { case WIRE_GOSSIPD_INIT:; + case WIRE_GOSSIPD_INIT_REPLY:; case WIRE_GOSSIPD_DEV_SET_TIME:; case WIRE_GOSSIPD_PING:; case WIRE_GOSSIPD_PING_REPLY:; @@ -139,6 +141,25 @@ bool fromwire_gossipd_init(const tal_t *ctx, const void *p, const struct chainpa return cursor != NULL; } +/* WIRE: GOSSIPD_INIT_REPLY */ +u8 *towire_gossipd_init_reply(const tal_t *ctx) +{ + u8 *p = tal_arr(ctx, u8, 0); + + towire_u16(&p, WIRE_GOSSIPD_INIT_REPLY); + + return memcheck(p, tal_count(p)); +} +bool fromwire_gossipd_init_reply(const void *p) +{ + const u8 *cursor = p; + size_t plen = tal_count(p); + + if (fromwire_u16(&cursor, &plen) != WIRE_GOSSIPD_INIT_REPLY) + return false; + return cursor != NULL; +} + /* WIRE: GOSSIPD_DEV_SET_TIME */ /* In developer mode */ u8 *towire_gossipd_dev_set_time(const tal_t *ctx, u32 dev_gossip_time) @@ -732,4 +753,4 @@ bool fromwire_gossipd_addgossip_reply(const tal_t *ctx, const void *p, wirestrin *err = fromwire_wirestring(ctx, &cursor, &plen); return cursor != NULL; } -// SHA256STAMP:bc9045727cefbbe29118c8eae928972fe009a4d9d8c9e903f8b35f006973f462 +// SHA256STAMP:6f6810a7e9c5e3e7dc1dd716b6a8de019516f6e82e3664bdf760647b5a987883 diff --git a/gossipd/gossipd_wiregen.h b/gossipd/gossipd_wiregen.h index 5059fb559d93..5e2c5f4a3cd4 100644 --- a/gossipd/gossipd_wiregen.h +++ b/gossipd/gossipd_wiregen.h @@ -15,6 +15,7 @@ enum gossipd_wire { /* Initialize the gossip daemon. */ WIRE_GOSSIPD_INIT = 3000, + WIRE_GOSSIPD_INIT_REPLY = 3100, /* In developer mode */ WIRE_GOSSIPD_DEV_SET_TIME = 3001, /* Ping/pong test. Waits for a reply if it expects one. */ @@ -72,6 +73,10 @@ bool gossipd_wire_is_defined(u16 type); u8 *towire_gossipd_init(const tal_t *ctx, const struct chainparams *chainparams, const struct feature_set *our_features, const struct node_id *id, const u8 rgb[3], const u8 alias[32], const struct wireaddr *announcable, u32 *dev_gossip_time, bool dev_fast_gossip, bool dev_fast_gossip_prune); bool fromwire_gossipd_init(const tal_t *ctx, const void *p, const struct chainparams **chainparams, struct feature_set **our_features, struct node_id *id, u8 rgb[3], u8 alias[32], struct wireaddr **announcable, u32 **dev_gossip_time, bool *dev_fast_gossip, bool *dev_fast_gossip_prune); +/* WIRE: GOSSIPD_INIT_REPLY */ +u8 *towire_gossipd_init_reply(const tal_t *ctx); +bool fromwire_gossipd_init_reply(const void *p); + /* WIRE: GOSSIPD_DEV_SET_TIME */ /* In developer mode */ u8 *towire_gossipd_dev_set_time(const tal_t *ctx, u32 dev_gossip_time); @@ -175,4 +180,4 @@ bool fromwire_gossipd_addgossip_reply(const tal_t *ctx, const void *p, wirestrin #endif /* LIGHTNING_GOSSIPD_GOSSIPD_WIREGEN_H */ -// SHA256STAMP:bc9045727cefbbe29118c8eae928972fe009a4d9d8c9e903f8b35f006973f462 +// SHA256STAMP:6f6810a7e9c5e3e7dc1dd716b6a8de019516f6e82e3664bdf760647b5a987883 diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 4063679e8a2e..1b2fd6a70175 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -148,6 +148,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIPD_SEND_ONIONMSG: case WIRE_GOSSIPD_ADDGOSSIP: /* This is a reply, so never gets through to here. */ + case WIRE_GOSSIPD_INIT_REPLY: case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY: case WIRE_GOSSIPD_DEV_COMPACT_STORE_REPLY: case WIRE_GOSSIPD_GET_STRIPPED_CUPDATE_REPLY: @@ -187,6 +188,16 @@ static void gossip_topology_synced(struct chain_topology *topo, void *unused) gossip_notify_new_block(topo->ld, get_block_height(topo)); } +/* We make sure gossipd is started before plugins (which may want gossip_map) */ +static void gossipd_init_done(struct subd *gossipd, + const u8 *msg, + const int *fds, + void *unused) +{ + /* Break out of loop, so we can begin */ + io_break(gossipd); +} + /* Create the `gossipd` subdaemon and send the initialization * message */ void gossip_init(struct lightningd *ld, int connectd_fd) @@ -207,7 +218,7 @@ void gossip_init(struct lightningd *ld, int connectd_fd) gossip_topology_synced, NULL); msg = towire_gossipd_init( - tmpctx, + NULL, chainparams, ld->our_features, &ld->id, @@ -217,7 +228,12 @@ void gossip_init(struct lightningd *ld, int connectd_fd) IFDEV(ld->dev_gossip_time ? &ld->dev_gossip_time: NULL, NULL), IFDEV(ld->dev_fast_gossip, false), IFDEV(ld->dev_fast_gossip_prune, false)); - subd_send_msg(ld->gossip, msg); + + subd_req(ld->gossip, ld->gossip, take(msg), -1, 0, + gossipd_init_done, NULL); + + /* Wait for gossipd_init_reply */ + io_loop(NULL, NULL); } void gossipd_notify_spend(struct lightningd *ld, diff --git a/plugins/topology.c b/plugins/topology.c index 47490f754a62..2fbe1db76bd3 100644 --- a/plugins/topology.c +++ b/plugins/topology.c @@ -20,24 +20,15 @@ #include /* Access via get_gossmap() */ +static struct gossmap *global_gossmap; static struct node_id local_id; static struct plugin *plugin; /* We load this on demand, since we can start before gossipd. */ static struct gossmap *get_gossmap(void) { - static struct gossmap *gossmap; - - if (gossmap) - gossmap_refresh(gossmap); - else { - gossmap = notleak_with_children(gossmap_load(NULL, - GOSSIP_STORE_FILENAME)); - if (!gossmap) - plugin_err(plugin, "Could not load gossmap %s: %s", - GOSSIP_STORE_FILENAME, strerror(errno)); - } - return gossmap; + gossmap_refresh(global_gossmap); + return global_gossmap; } /* Convenience global since route_score_fuzz doesn't take args. 0 to 1. */ @@ -677,6 +668,12 @@ static const char *init(struct plugin *p, take(json_out_obj(NULL, NULL, NULL)), "{id:%}", JSON_SCAN(json_to_node_id, &local_id)); + global_gossmap = notleak_with_children(gossmap_load(NULL, + GOSSIP_STORE_FILENAME)); + if (!global_gossmap) + plugin_err(plugin, "Could not load gossmap %s: %s", + GOSSIP_STORE_FILENAME, strerror(errno)); + return NULL; }