lightningd: wait for gossipd to finish initalizing before starting plugins.

This mainly helps our CI under valgrind, which starts a fresh instance
and immediately calls the invoice command.  This can cause the topology
plugin to try to access the gossmap file before it's created.

We can also move the gossmap reading in topology to init time.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2021-06-15 06:37:39 +09:30
parent 7e7ab4cb3b
commit 75720ad0e1
6 changed files with 61 additions and 16 deletions

View File

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

View File

@@ -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,
1 #include <common/cryptomsg.h>
16 msgdata,gossipd_init,dev_fast_gossip_prune,bool,
17 # In developer mode, we can mess with time. msgtype,gossipd_init_reply,3100
18 msgtype,gossipd_dev_set_time,3001 # In developer mode, we can mess with time.
19 msgtype,gossipd_dev_set_time,3001
20 msgdata,gossipd_dev_set_time,dev_gossip_time,u32,
21 msgdata,gossipd_dev_set_time,dev_gossip_time,u32, # Ping/pong test. Waits for a reply if it expects one.
22 # Ping/pong test. Waits for a reply if it expects one. msgtype,gossipd_ping,3008
23 msgtype,gossipd_ping,3008 msgdata,gossipd_ping,id,node_id,

View File

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

View File

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

View File

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

View File

@@ -20,24 +20,15 @@
#include <wire/peer_wire.h>
/* 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;
}