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