gossipd: add dying marker to channel_announcement/channel_update.

We don't actually delete them for 12 blocks, but we can't avoid
propagating them.  We don't mark node_announcements, which is a bit
weird, but avoids us tracking logic to un-dying them if a channel is
opened.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2023-07-19 16:05:31 +09:30
parent 8178b7389f
commit d16797ce58
5 changed files with 66 additions and 0 deletions

View File

@@ -579,6 +579,40 @@ u64 gossip_store_add_private_update(struct gossip_store *gs, const u8 *update)
return gossip_store_add(gs, pupdate, 0, false, false, NULL);
}
void gossip_store_mark_dying(struct gossip_store *gs,
const struct broadcastable *bcast,
int type)
{
const u8 *msg;
be16 flags;
/* Should never get here during loading! */
assert(gs->writable);
/* Should never try to overwrite version */
assert(bcast->index);
/* Sanity check, that this is a channel announcement */
msg = gossip_store_get(tmpctx, gs, bcast->index);
if (fromwire_peektype(msg) != type) {
status_broken("gossip_store incorrect dying msg not %u @%u of %"PRIu64": %s",
type, bcast->index, gs->len, tal_hex(tmpctx, msg));
return;
}
if (pread(gs->fd, &flags, sizeof(flags), bcast->index) != sizeof(flags)) {
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Could not read to mark dying at %u/%"PRIu64": %s",
bcast->index, gs->len, strerror(errno));
}
flags |= cpu_to_be16(GOSSIP_STORE_DYING_BIT);
if (pwrite(gs->fd, &flags, sizeof(flags), bcast->index) != sizeof(flags))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Failed writing flags to dying @%u: %s",
bcast->index, strerror(errno));
}
/* Returns index of following entry. */
static u32 delete_by_index(struct gossip_store *gs, u32 index, int type)
{

View File

@@ -76,6 +76,17 @@ void gossip_store_mark_channel_zombie(struct gossip_store *gs,
void gossip_store_mark_cupdate_zombie(struct gossip_store *gs,
struct broadcastable *bcast);
/**
* Mark this channel_announcement/channel_update as dying.
*
* We'll clean it up in 12 blocks, but this tells connectd not to gossip
* about it.
*/
void gossip_store_mark_dying(struct gossip_store *gs,
const struct broadcastable *bcast,
int type);
/**
* Direct store accessor: loads gossip msg back from store.
*

View File

@@ -2279,6 +2279,17 @@ void routing_channel_spent(struct routing_state *rstate,
msg = towire_gossip_store_chan_dying(tmpctx, &chan->scid, deadline);
index = gossip_store_add(rstate->gs, msg, 0, false, false, NULL);
/* Mark it dying, so we don't gossip it */
gossip_store_mark_dying(rstate->gs, &chan->bcast,
WIRE_CHANNEL_ANNOUNCEMENT);
for (int dir = 0; dir < ARRAY_SIZE(chan->half); dir++) {
if (is_halfchan_defined(&chan->half[dir])) {
gossip_store_mark_dying(rstate->gs,
&chan->half[dir].bcast,
WIRE_CHANNEL_UPDATE);
}
}
/* Remember locally so we can kill it in 12 blocks */
status_debug("channel %s closing soon due"
" to the funding outpoint being spent",

View File

@@ -86,6 +86,11 @@ const u8 *gossip_store_get_private_update(const tal_t *ctx UNNEEDED,
void gossip_store_mark_channel_deleted(struct gossip_store *gs UNNEEDED,
const struct short_channel_id *scid UNNEEDED)
{ fprintf(stderr, "gossip_store_mark_channel_deleted called!\n"); abort(); }
/* Generated stub for gossip_store_mark_dying */
void gossip_store_mark_dying(struct gossip_store *gs UNNEEDED,
const struct broadcastable *bcast UNNEEDED,
int type UNNEEDED)
{ fprintf(stderr, "gossip_store_mark_dying called!\n"); abort(); }
/* Generated stub for gossip_store_new */
struct gossip_store *gossip_store_new(struct routing_state *rstate UNNEEDED)
{ fprintf(stderr, "gossip_store_new called!\n"); abort(); }

View File

@@ -57,6 +57,11 @@ const u8 *gossip_store_get_private_update(const tal_t *ctx UNNEEDED,
void gossip_store_mark_channel_deleted(struct gossip_store *gs UNNEEDED,
const struct short_channel_id *scid UNNEEDED)
{ fprintf(stderr, "gossip_store_mark_channel_deleted called!\n"); abort(); }
/* Generated stub for gossip_store_mark_dying */
void gossip_store_mark_dying(struct gossip_store *gs UNNEEDED,
const struct broadcastable *bcast UNNEEDED,
int type UNNEEDED)
{ fprintf(stderr, "gossip_store_mark_dying called!\n"); abort(); }
/* Generated stub for memleak_add_helper_ */
void memleak_add_helper_(const tal_t *p UNNEEDED, void (*cb)(struct htable *memtable UNNEEDED,
const tal_t *)){ }