diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c index abc001e42139..f2862895a737 100644 --- a/gossipd/gossip_store.c +++ b/gossipd/gossip_store.c @@ -70,7 +70,7 @@ static ssize_t gossip_pwritev(int fd, const struct iovec *iov, int iovcnt, #endif /* !HAVE_PWRITEV */ static bool append_msg(int fd, const u8 *msg, u32 timestamp, - bool zombie, bool spam, u64 *len) + bool zombie, bool spam, bool dying, u64 *len) { struct gossip_hdr hdr; u32 msglen; @@ -86,6 +86,8 @@ static bool append_msg(int fd, const u8 *msg, u32 timestamp, hdr.flags |= CPU_TO_BE16(GOSSIP_STORE_RATELIMIT_BIT); if (zombie) hdr.flags |= CPU_TO_BE16(GOSSIP_STORE_ZOMBIE_BIT); + if (dying) + hdr.flags |= CPU_TO_BE16(GOSSIP_STORE_DYING_BIT); hdr.crc = cpu_to_be32(crc32c(timestamp, msg, msglen)); hdr.timestamp = cpu_to_be32(timestamp); @@ -246,7 +248,7 @@ static u32 gossip_store_compact_offline(struct routing_state *rstate) oldlen = lseek(old_fd, SEEK_END, 0); newlen = lseek(new_fd, SEEK_END, 0); append_msg(old_fd, towire_gossip_store_ended(tmpctx, newlen), - 0, false, false, &oldlen); + 0, false, false, false, &oldlen); close(old_fd); status_debug("gossip_store_compact_offline: %zu deleted, %zu copied", deleted, count); @@ -526,7 +528,7 @@ bool gossip_store_compact(struct gossip_store *gs) /* Write end marker now new one is ready */ append_msg(gs->fd, towire_gossip_store_ended(tmpctx, len), - 0, false, false, &gs->len); + 0, false, false, false, &gs->len); gs->count = count; gs->deleted = 0; @@ -547,19 +549,19 @@ bool gossip_store_compact(struct gossip_store *gs) u64 gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg, u32 timestamp, bool zombie, - bool spam, const u8 *addendum) + bool spam, bool dying, const u8 *addendum) { u64 off = gs->len; /* Should never get here during loading! */ assert(gs->writable); - if (!append_msg(gs->fd, gossip_msg, timestamp, zombie, spam, &gs->len)) { + if (!append_msg(gs->fd, gossip_msg, timestamp, zombie, spam, dying, &gs->len)) { status_broken("Failed writing to gossip store: %s", strerror(errno)); return 0; } - if (addendum && !append_msg(gs->fd, addendum, 0, false, false, &gs->len)) { + if (addendum && !append_msg(gs->fd, addendum, 0, false, false, false, &gs->len)) { status_broken("Failed writing addendum to gossip store: %s", strerror(errno)); return 0; @@ -576,7 +578,7 @@ u64 gossip_store_add_private_update(struct gossip_store *gs, const u8 *update) /* A local update for an unannounced channel: not broadcastable, but * otherwise the same as a normal channel_update */ const u8 *pupdate = towire_gossip_store_private_update(tmpctx, update); - return gossip_store_add(gs, pupdate, 0, false, false, NULL); + return gossip_store_add(gs, pupdate, 0, false, false, false, NULL); } void gossip_store_mark_dying(struct gossip_store *gs, @@ -684,7 +686,7 @@ void gossip_store_mark_channel_deleted(struct gossip_store *gs, const struct short_channel_id *scid) { gossip_store_add(gs, towire_gossip_store_delete_chan(tmpctx, scid), - 0, false, false, NULL); + 0, false, false, false, NULL); } static void mark_zombie(struct gossip_store *gs, diff --git a/gossipd/gossip_store.h b/gossipd/gossip_store.h index 698eb64718db..a8d7d7bc6888 100644 --- a/gossipd/gossip_store.h +++ b/gossipd/gossip_store.h @@ -38,14 +38,14 @@ u64 gossip_store_add_private_update(struct gossip_store *gs, const u8 *update); * @gs: gossip store * @gossip_msg: the gossip message to insert. * @timestamp: the timestamp for filtering of this messsage. - * @push: true if this should be sent to peers despite any timestamp filters. - * @spam: true if this message is rate-limited and squelched to peers. * @zombie: true if this channel is missing a current channel_update. + * @spam: true if this message is rate-limited and squelched to peers. + * @dying: true if this message is for a dying channel. * @addendum: another message to append immediately after this * (for appending amounts to channel_announcements for internal use). */ u64 gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg, - u32 timestamp, bool zombie, bool spam, + u32 timestamp, bool zombie, bool spam, bool dying, const u8 *addendum); diff --git a/gossipd/routing.c b/gossipd/routing.c index ffc7daddd92b..244d54a0d04c 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -465,6 +465,7 @@ static void force_node_announce_rexmit(struct routing_state *rstate, node->bcast.timestamp, false, false, + false, NULL); if (node->rgraph.index == initial_bcast_index){ node->rgraph.index = node->bcast.index; @@ -478,6 +479,7 @@ static void force_node_announce_rexmit(struct routing_state *rstate, node->rgraph.timestamp, false, true, + false, NULL); } } @@ -847,6 +849,7 @@ static void add_channel_announce_to_broadcast(struct routing_state *rstate, chan->bcast.timestamp, false, false, + false, addendum); rstate->local_channel_announced |= is_local; } @@ -1315,6 +1318,16 @@ static void delete_spam_update(struct routing_state *rstate, hc->rgraph.timestamp = hc->bcast.timestamp; } +static bool is_chan_dying(struct routing_state *rstate, + const struct short_channel_id *scid) +{ + for (size_t i = 0; i < tal_count(rstate->dying_channels); i++) { + if (short_channel_id_eq(&rstate->dying_channels[i].scid, scid)) + return true; + } + return false; +} + bool routing_add_channel_update(struct routing_state *rstate, const u8 *update TAKES, u32 index, @@ -1339,6 +1352,7 @@ bool routing_add_channel_update(struct routing_state *rstate, struct amount_sat sat; bool spam; bool zombie; + bool dying; /* Make sure we own msg, even if we don't save it. */ if (taken(update)) @@ -1360,6 +1374,7 @@ bool routing_add_channel_update(struct routing_state *rstate, uc = NULL; sat = chan->sat; zombie = is_chan_zombie(chan); + dying = is_chan_dying(rstate, &short_channel_id); } else { /* Maybe announcement was waiting for this update? */ uc = get_unupdated_channel(rstate, &short_channel_id); @@ -1369,6 +1384,7 @@ bool routing_add_channel_update(struct routing_state *rstate, sat = uc->sat; /* When loading zombies from the store. */ zombie = force_zombie_flag; + dying = false; } /* Reject update if the `htlc_maximum_msat` is greater @@ -1531,7 +1547,7 @@ bool routing_add_channel_update(struct routing_state *rstate, chan->bcast.index = gossip_store_add(rstate->gs, zombie_announcement, chan->bcast.timestamp, - false, false, zombie_addendum); + false, false, false, zombie_addendum); /* Deletion of the old addendum is optional. */ /* This opposing channel_update has been stashed away. Now that * there are two valid updates, this one gets restored. */ @@ -1554,12 +1570,12 @@ bool routing_add_channel_update(struct routing_state *rstate, chan->half[!direction].bcast.index = gossip_store_add(rstate->gs, zombie_update[0], chan->half[!direction].bcast.timestamp, - false, false, NULL); + false, false, false, NULL); if (zombie_update[1]) chan->half[!direction].rgraph.index = gossip_store_add(rstate->gs, zombie_update[1], chan->half[!direction].rgraph.timestamp, - false, true, NULL); + false, true, false, NULL); else chan->half[!direction].rgraph.index = chan->half[!direction].bcast.index; @@ -1577,7 +1593,7 @@ bool routing_add_channel_update(struct routing_state *rstate, } else { hc->rgraph.index = gossip_store_add(rstate->gs, update, timestamp, - zombie, spam, NULL); + zombie, spam, dying, NULL); if (hc->bcast.timestamp > rstate->last_timestamp && hc->bcast.timestamp < time_now().ts.tv_sec) rstate->last_timestamp = hc->bcast.timestamp; @@ -1596,8 +1612,9 @@ bool routing_add_channel_update(struct routing_state *rstate, } status_peer_debug(source_peer, - "Received %schannel_update for channel %s/%d now %s", + "Received %schannel_update for %schannel %s/%d now %s", ignore_timestamp ? "(forced) " : "", + dying ? "dying ": "", type_to_string(tmpctx, struct short_channel_id, &short_channel_id), channel_flags & 0x01, @@ -1899,7 +1916,7 @@ bool routing_add_node_announcement(struct routing_state *rstate, } else { node->rgraph.index = gossip_store_add(rstate->gs, msg, timestamp, - false, spam, NULL); + false, spam, false, NULL); if (node->bcast.timestamp > rstate->last_timestamp && node->bcast.timestamp < time_now().ts.tv_sec) rstate->last_timestamp = node->bcast.timestamp; @@ -2131,7 +2148,7 @@ bool routing_add_private_channel(struct routing_state *rstate, u8 *msg = towire_gossip_store_private_channel(tmpctx, capacity, chan_ann); - index = gossip_store_add(rstate->gs, msg, 0, false, false, + index = gossip_store_add(rstate->gs, msg, 0, false, false, false, NULL); } chan->bcast.index = index; @@ -2277,7 +2294,7 @@ void routing_channel_spent(struct routing_state *rstate, /* Save to gossip_store in case we restart */ msg = towire_gossip_store_chan_dying(tmpctx, &chan->scid, deadline); - index = gossip_store_add(rstate->gs, msg, 0, false, false, NULL); + index = gossip_store_add(rstate->gs, msg, 0, false, false, false, NULL); /* Mark it dying, so we don't gossip it */ gossip_store_mark_dying(rstate->gs, &chan->bcast, diff --git a/gossipd/test/run-check_channel_announcement.c b/gossipd/test/run-check_channel_announcement.c index bd2d70071cef..2a307ef36d0b 100644 --- a/gossipd/test/run-check_channel_announcement.c +++ b/gossipd/test/run-check_channel_announcement.c @@ -61,7 +61,7 @@ bool cupdate_different(struct gossip_store *gs UNNEEDED, { fprintf(stderr, "cupdate_different called!\n"); abort(); } /* Generated stub for gossip_store_add */ u64 gossip_store_add(struct gossip_store *gs UNNEEDED, const u8 *gossip_msg UNNEEDED, - u32 timestamp UNNEEDED, bool zombie UNNEEDED, bool spam UNNEEDED, + u32 timestamp UNNEEDED, bool zombie UNNEEDED, bool spam UNNEEDED, bool dying UNNEEDED, const u8 *addendum UNNEEDED) { fprintf(stderr, "gossip_store_add called!\n"); abort(); } /* Generated stub for gossip_store_add_private_update */ diff --git a/gossipd/test/run-txout_failure.c b/gossipd/test/run-txout_failure.c index 2eb26db8a737..1fb6271990fb 100644 --- a/gossipd/test/run-txout_failure.c +++ b/gossipd/test/run-txout_failure.c @@ -32,7 +32,7 @@ bool cupdate_different(struct gossip_store *gs UNNEEDED, { fprintf(stderr, "cupdate_different called!\n"); abort(); } /* Generated stub for gossip_store_add */ u64 gossip_store_add(struct gossip_store *gs UNNEEDED, const u8 *gossip_msg UNNEEDED, - u32 timestamp UNNEEDED, bool zombie UNNEEDED, bool spam UNNEEDED, + u32 timestamp UNNEEDED, bool zombie UNNEEDED, bool spam UNNEEDED, bool dying UNNEEDED, const u8 *addendum UNNEEDED) { fprintf(stderr, "gossip_store_add called!\n"); abort(); } /* Generated stub for gossip_store_add_private_update */