From 6f9c5f2936d9919f9a7f271c482f6146be49ca49 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sun, 22 Sep 2019 11:36:43 +0930 Subject: [PATCH] gossipd: get fed the blockheight from lightningd when we know it. This will let gossipd be more intelligent about gossiping before we're synced, and also it might know how far behind we are. Signed-off-by: Rusty Russell --- gossipd/gossip_wire.csv | 4 ++++ gossipd/gossipd.c | 13 +++++++++++++ gossipd/gossipd.h | 3 +++ gossipd/test/run-crc32_of_update.c | 3 +++ gossipd/test/run-extended-info.c | 3 +++ lightningd/gossip_control.c | 21 +++++++++++++++++++++ lightningd/gossip_control.h | 2 ++ lightningd/lightningd.c | 1 + lightningd/test/run-find_my_abspath.c | 3 +++ 9 files changed, 53 insertions(+) diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index d90434291..0e58caf93 100644 --- a/gossipd/gossip_wire.csv +++ b/gossipd/gossip_wire.csv @@ -164,3 +164,7 @@ msgdata,gossip_get_incoming_channels,private_too,?bool, msgtype,gossip_get_incoming_channels_reply,3125 msgdata,gossip_get_incoming_channels_reply,num,u16, msgdata,gossip_get_incoming_channels_reply,route_info,route_info,num + +# master -> gossipd: blockheight increased. +msgtype,gossip_new_blockheight,3026 +msgdata,gossip_new_blockheight,blockheight,u32, diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 33d90ac6c..ae16d9978 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -2344,6 +2344,15 @@ static struct io_plan *get_incoming_channels(struct io_conn *conn, return daemon_conn_read_next(conn, daemon->master); } +static struct io_plan *new_blockheight(struct io_conn *conn, + struct daemon *daemon, + const u8 *msg) +{ + if (!fromwire_gossip_new_blockheight(msg, &daemon->current_blockheight)) + master_badmsg(WIRE_GOSSIP_NEW_BLOCKHEIGHT, msg); + return daemon_conn_read_next(conn, daemon->master); +} + #if DEVELOPER static struct io_plan *query_scids_req(struct io_conn *conn, struct daemon *daemon, @@ -2801,6 +2810,9 @@ static struct io_plan *recv_req(struct io_conn *conn, case WIRE_GOSSIP_GET_INCOMING_CHANNELS: return get_incoming_channels(conn, daemon, msg); + case WIRE_GOSSIP_NEW_BLOCKHEIGHT: + return new_blockheight(conn, daemon, msg); + #if DEVELOPER case WIRE_GOSSIP_QUERY_SCIDS: return query_scids_req(conn, daemon, msg); @@ -2875,6 +2887,7 @@ int main(int argc, char *argv[]) daemon->unknown_scids = tal_arr(daemon, struct short_channel_id, 0); daemon->gossip_missing = NULL; daemon->node_announce_timer = NULL; + daemon->current_blockheight = 0; /* i.e. unknown */ /* Note the use of time_mono() here. That's a monotonic clock, which * is really useful: it can only be used to measure relative events diff --git a/gossipd/gossipd.h b/gossipd/gossipd.h index 09c814cd9..f9d3e2514 100644 --- a/gossipd/gossipd.h +++ b/gossipd/gossipd.h @@ -18,6 +18,9 @@ struct daemon { /* Peers we are gossiping to: id is unique */ struct list_head peers; + /* Current blockheight: 0 means we're not up-to-date. */ + u32 current_blockheight; + /* Connection to lightningd. */ struct daemon_conn *master; diff --git a/gossipd/test/run-crc32_of_update.c b/gossipd/test/run-crc32_of_update.c index 6b25a5c3a..50ba85211 100644 --- a/gossipd/test/run-crc32_of_update.c +++ b/gossipd/test/run-crc32_of_update.c @@ -100,6 +100,9 @@ bool fromwire_gossip_get_txout_reply(const tal_t *ctx UNNEEDED, const void *p UN /* Generated stub for fromwire_gossip_local_channel_close */ bool fromwire_gossip_local_channel_close(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED) { fprintf(stderr, "fromwire_gossip_local_channel_close called!\n"); abort(); } +/* Generated stub for fromwire_gossip_new_blockheight */ +bool fromwire_gossip_new_blockheight(const void *p UNNEEDED, u32 *blockheight UNNEEDED) +{ fprintf(stderr, "fromwire_gossip_new_blockheight called!\n"); abort(); } /* Generated stub for fromwire_gossip_new_peer */ bool fromwire_gossip_new_peer(const void *p UNNEEDED, struct node_id *id UNNEEDED, bool *gossip_queries_feature UNNEEDED, bool *initial_routing_sync UNNEEDED) { fprintf(stderr, "fromwire_gossip_new_peer called!\n"); abort(); } diff --git a/gossipd/test/run-extended-info.c b/gossipd/test/run-extended-info.c index 1d44f4649..9fc703fee 100644 --- a/gossipd/test/run-extended-info.c +++ b/gossipd/test/run-extended-info.c @@ -108,6 +108,9 @@ bool fromwire_gossip_get_txout_reply(const tal_t *ctx UNNEEDED, const void *p UN /* Generated stub for fromwire_gossip_local_channel_close */ bool fromwire_gossip_local_channel_close(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED) { fprintf(stderr, "fromwire_gossip_local_channel_close called!\n"); abort(); } +/* Generated stub for fromwire_gossip_new_blockheight */ +bool fromwire_gossip_new_blockheight(const void *p UNNEEDED, u32 *blockheight UNNEEDED) +{ fprintf(stderr, "fromwire_gossip_new_blockheight called!\n"); abort(); } /* Generated stub for fromwire_gossip_new_peer */ bool fromwire_gossip_new_peer(const void *p UNNEEDED, struct node_id *id UNNEEDED, bool *gossip_queries_feature UNNEEDED, bool *initial_routing_sync UNNEEDED) { fprintf(stderr, "fromwire_gossip_new_peer called!\n"); abort(); } diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index ea37d1560..34065dcea 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -152,6 +152,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIP_DEV_MEMLEAK: case WIRE_GOSSIP_DEV_COMPACT_STORE: case WIRE_GOSSIP_DEV_SET_TIME: + case WIRE_GOSSIP_NEW_BLOCKHEIGHT: /* This is a reply, so never gets through to here. */ case WIRE_GOSSIP_GETNODES_REPLY: case WIRE_GOSSIP_GETROUTE_REPLY: @@ -175,6 +176,22 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) return 0; } +void gossip_notify_new_block(struct lightningd *ld, u32 blockheight) +{ + /* Only notify gossipd once we're synced. */ + if (!topology_synced(ld->topology)) + return; + + subd_send_msg(ld->gossip, + take(towire_gossip_new_blockheight(NULL, blockheight))); +} + +static void gossip_topology_synced(struct chain_topology *topo, void *unused) +{ + /* Now we start telling gossipd about blocks. */ + gossip_notify_new_block(topo->ld, get_block_height(topo)); +} + /* Create the `gossipd` subdaemon and send the initialization * message */ void gossip_init(struct lightningd *ld, int connectd_fd) @@ -190,6 +207,10 @@ void gossip_init(struct lightningd *ld, int connectd_fd) if (!ld->gossip) err(1, "Could not subdaemon gossip"); + /* We haven't started topology yet, so tell us when we're synced. */ + topology_add_sync_waiter(ld->gossip, ld->topology, + gossip_topology_synced, NULL); + msg = towire_gossipctl_init( tmpctx, &get_chainparams(ld)->genesis_blockhash, &ld->id, diff --git a/lightningd/gossip_control.h b/lightningd/gossip_control.h index bc33cbc19..7d6254e29 100644 --- a/lightningd/gossip_control.h +++ b/lightningd/gossip_control.h @@ -12,4 +12,6 @@ void gossip_init(struct lightningd *ld, int connectd_fd); void gossipd_notify_spend(struct lightningd *ld, const struct short_channel_id *scid); +void gossip_notify_new_block(struct lightningd *ld, u32 blockheight); + #endif /* LIGHTNING_LIGHTNINGD_GOSSIP_CONTROL_H */ diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 144b95a91..b41420de2 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -586,6 +586,7 @@ void notify_new_block(struct lightningd *ld, u32 block_height) /* Inform our subcomponents individually. */ htlcs_notify_new_block(ld, block_height); channel_notify_new_block(ld, block_height); + gossip_notify_new_block(ld, block_height); } static void on_sigint(int _ UNUSED) diff --git a/lightningd/test/run-find_my_abspath.c b/lightningd/test/run-find_my_abspath.c index 4d645e333..948f9fe8a 100644 --- a/lightningd/test/run-find_my_abspath.c +++ b/lightningd/test/run-find_my_abspath.c @@ -81,6 +81,9 @@ struct log_book *get_log_book(const struct log *log UNNEEDED) /* Generated stub for gossip_init */ void gossip_init(struct lightningd *ld UNNEEDED, int connectd_fd UNNEEDED) { fprintf(stderr, "gossip_init called!\n"); abort(); } +/* Generated stub for gossip_notify_new_block */ +void gossip_notify_new_block(struct lightningd *ld UNNEEDED, u32 blockheight UNNEEDED) +{ fprintf(stderr, "gossip_notify_new_block called!\n"); abort(); } /* Generated stub for handle_early_opts */ void handle_early_opts(struct lightningd *ld UNNEEDED, int argc UNNEEDED, char *argv[]) { fprintf(stderr, "handle_early_opts called!\n"); abort(); }