diff --git a/gossipd/gossip_generation.c b/gossipd/gossip_generation.c index 22497709e..2653f479a 100644 --- a/gossipd/gossip_generation.c +++ b/gossipd/gossip_generation.c @@ -811,6 +811,26 @@ void local_disable_chan(struct daemon *daemon, const struct chan *chan, int dire defer_update(daemon, 0xFFFFFFFF, chan, direction, take(update)); } +/* lightningd tells us it used the local channel update. */ +void handle_used_local_channel_update(struct daemon *daemon, const u8 *msg) +{ + struct short_channel_id scid; + struct chan *chan; + + if (!fromwire_gossipd_used_local_channel_update(msg, &scid)) + master_badmsg(WIRE_GOSSIPD_USED_LOCAL_CHANNEL_UPDATE, msg); + + chan = get_channel(daemon->rstate, &scid); + /* Might have closed in meantime, but v unlikely! */ + if (!chan) { + status_broken("used_local_channel_update on unknown %s", + type_to_string(tmpctx, struct short_channel_id, + &scid)); + return; + } + local_channel_update_latest(daemon, chan); +} + void local_enable_chan(struct daemon *daemon, const struct chan *chan, int direction) { struct deferred_update *du; diff --git a/gossipd/gossip_generation.h b/gossipd/gossip_generation.h index 2e7b396f5..adc3f81db 100644 --- a/gossipd/gossip_generation.h +++ b/gossipd/gossip_generation.h @@ -53,4 +53,7 @@ bool handle_local_channel_update(struct daemon *daemon, const struct node_id *src, const u8 *msg); +/* lightningd tells us it used the last channel_update we sent. */ +void handle_used_local_channel_update(struct daemon *daemon, const u8 *msg); + #endif /* LIGHTNING_GOSSIPD_GOSSIP_GENERATION_H */ diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index fcde98ba1..06ff2deb4 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -1413,6 +1413,10 @@ static struct io_plan *recv_req(struct io_conn *conn, case WIRE_GOSSIPD_GET_ADDRS: return handle_get_address(conn, daemon, msg); + case WIRE_GOSSIPD_USED_LOCAL_CHANNEL_UPDATE: + handle_used_local_channel_update(daemon, msg); + goto done; + #if DEVELOPER case WIRE_GOSSIPD_DEV_SET_MAX_SCIDS_ENCODE_SIZE: dev_set_max_scids_encode_size(daemon, msg); diff --git a/gossipd/gossipd_wire.csv b/gossipd/gossipd_wire.csv index 6df53358a..96d42fd1b 100644 --- a/gossipd/gossipd_wire.csv +++ b/gossipd/gossipd_wire.csv @@ -122,3 +122,7 @@ msgtype,gossipd_got_local_channel_update,3151 msgdata,gossipd_got_local_channel_update,scid,short_channel_id, msgdata,gossipd_got_local_channel_update,len,u16, msgdata,gossipd_got_local_channel_update,channel_update,u8,len + +# Tell gossipd we used the channel update (in case it was deferred) +msgtype,gossipd_used_local_channel_update,3052 +msgdata,gossipd_used_local_channel_update,scid,short_channel_id, diff --git a/gossipd/test/run-check_node_announcement.c b/gossipd/test/run-check_node_announcement.c index ac5c80f27..4104556fa 100644 --- a/gossipd/test/run-check_node_announcement.c +++ b/gossipd/test/run-check_node_announcement.c @@ -39,6 +39,9 @@ char *fmt_wireaddr_without_port(const tal_t *ctx UNNEEDED, const struct wireaddr /* Generated stub for fromwire_gossipd_local_channel_update */ bool fromwire_gossipd_local_channel_update(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, bool *disable UNNEEDED, u16 *cltv_expiry_delta UNNEEDED, struct amount_msat *htlc_minimum_msat UNNEEDED, u32 *fee_base_msat UNNEEDED, u32 *fee_proportional_millionths UNNEEDED, struct amount_msat *htlc_maximum_msat UNNEEDED) { fprintf(stderr, "fromwire_gossipd_local_channel_update called!\n"); abort(); } +/* Generated stub for fromwire_gossipd_used_local_channel_update */ +bool fromwire_gossipd_used_local_channel_update(const void *p UNNEEDED, struct short_channel_id *scid UNNEEDED) +{ fprintf(stderr, "fromwire_gossipd_used_local_channel_update called!\n"); abort(); } /* Generated stub for fromwire_hsmd_cupdate_sig_reply */ bool fromwire_hsmd_cupdate_sig_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **cu UNNEEDED) { fprintf(stderr, "fromwire_hsmd_cupdate_sig_reply called!\n"); abort(); } @@ -78,6 +81,9 @@ void json_object_end(struct json_stream *js UNNEEDED) /* Generated stub for json_object_start */ void json_object_start(struct json_stream *ks UNNEEDED, const char *fieldname UNNEEDED) { fprintf(stderr, "json_object_start called!\n"); abort(); } +/* Generated stub for master_badmsg */ +void master_badmsg(u32 type_expected UNNEEDED, const u8 *msg) +{ fprintf(stderr, "master_badmsg called!\n"); abort(); } /* Generated stub for new_onionreply */ struct onionreply *new_onionreply(const tal_t *ctx UNNEEDED, const u8 *contents TAKES UNNEEDED) { fprintf(stderr, "new_onionreply called!\n"); abort(); } diff --git a/gossipd/test/run-crc32_of_update.c b/gossipd/test/run-crc32_of_update.c index 9c0fef29d..7d9b64037 100644 --- a/gossipd/test/run-crc32_of_update.c +++ b/gossipd/test/run-crc32_of_update.c @@ -60,6 +60,9 @@ bool fromwire_gossipd_dev_set_max_scids_encode_size(const void *p UNNEEDED, u32 /* Generated stub for fromwire_gossipd_local_channel_update */ bool fromwire_gossipd_local_channel_update(const void *p UNNEEDED, struct short_channel_id *short_channel_id UNNEEDED, bool *disable UNNEEDED, u16 *cltv_expiry_delta UNNEEDED, struct amount_msat *htlc_minimum_msat UNNEEDED, u32 *fee_base_msat UNNEEDED, u32 *fee_proportional_millionths UNNEEDED, struct amount_msat *htlc_maximum_msat UNNEEDED) { fprintf(stderr, "fromwire_gossipd_local_channel_update called!\n"); abort(); } +/* Generated stub for fromwire_gossipd_used_local_channel_update */ +bool fromwire_gossipd_used_local_channel_update(const void *p UNNEEDED, struct short_channel_id *scid UNNEEDED) +{ fprintf(stderr, "fromwire_gossipd_used_local_channel_update called!\n"); abort(); } /* Generated stub for fromwire_hsmd_cupdate_sig_reply */ bool fromwire_hsmd_cupdate_sig_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, u8 **cu UNNEEDED) { fprintf(stderr, "fromwire_hsmd_cupdate_sig_reply called!\n"); abort(); } diff --git a/gossipd/test/run-onion_message.c b/gossipd/test/run-onion_message.c index 66bad4d69..13b610fe1 100644 --- a/gossipd/test/run-onion_message.c +++ b/gossipd/test/run-onion_message.c @@ -183,6 +183,9 @@ const u8 *handle_reply_channel_range(struct peer *peer UNNEEDED, const u8 *msg U /* Generated stub for handle_reply_short_channel_ids_end */ const u8 *handle_reply_short_channel_ids_end(struct peer *peer UNNEEDED, const u8 *msg UNNEEDED) { fprintf(stderr, "handle_reply_short_channel_ids_end called!\n"); abort(); } +/* Generated stub for handle_used_local_channel_update */ +void handle_used_local_channel_update(struct daemon *daemon UNNEEDED, const u8 *msg UNNEEDED) +{ fprintf(stderr, "handle_used_local_channel_update called!\n"); abort(); } /* Generated stub for json_add_member */ void json_add_member(struct json_stream *js UNNEEDED, const char *fieldname UNNEEDED, diff --git a/lightningd/channel.h b/lightningd/channel.h index 729ac8599..091346f2c 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -474,4 +474,6 @@ void channel_set_billboard(struct channel *channel, bool perm, struct htlc_in *channel_has_htlc_in(struct channel *channel); struct htlc_out *channel_has_htlc_out(struct channel *channel); +const u8 *get_channel_update(struct channel *channel); + #endif /* LIGHTNING_LIGHTNINGD_CHANNEL_H */ diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 11b2463e5..090f4ad41 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -135,6 +135,17 @@ static void handle_local_channel_update(struct lightningd *ld, const u8 *msg) channel->channel_update = tal_steal(channel, update); } +const u8 *get_channel_update(struct channel *channel) +{ + /* Tell gossipd we're using it (if shutting down, might be NULL) */ + if (channel->channel_update && channel->peer->ld->gossip) { + subd_send_msg(channel->peer->ld->gossip, + take(towire_gossipd_used_local_channel_update + (NULL, channel->scid))); + } + return channel->channel_update; +} + static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) { enum gossipd_wire t = fromwire_peektype(msg); @@ -156,6 +167,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIPD_SEND_ONIONMSG: case WIRE_GOSSIPD_ADDGOSSIP: case WIRE_GOSSIPD_GET_ADDRS: + case WIRE_GOSSIPD_USED_LOCAL_CHANNEL_UPDATE: /* This is a reply, so never gets through to here. */ case WIRE_GOSSIPD_INIT_REPLY: case WIRE_GOSSIPD_DEV_MEMLEAK_REPLY: