From bc1aabb01452cf612c18c4666add464802dfb1f5 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 4 Oct 2024 08:48:53 +0930 Subject: [PATCH] gossmap: don't crash on localmods on non-existant channels. We allow adding them, but crash when we remove the localmods. Yet this could theoretically happen if a channel we modified was removed from the gossmap, anyway. Reported-by: Lagrang3 Signed-off-by: Rusty Russell --- common/gossmap.c | 4 ++++ common/test/run-gossmap_local.c | 11 ++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/common/gossmap.c b/common/gossmap.c index 068a25c41..5427c5e1c 100644 --- a/common/gossmap.c +++ b/common/gossmap.c @@ -980,6 +980,10 @@ void gossmap_remove_localmods(struct gossmap *map, const struct localmod *mod = &localmods->mods[i]; struct gossmap_chan *chan = gossmap_find_chan(map, &mod->scid); + /* If there was no channel, ignore */ + if (!chan) + continue; + /* If that's a local channel, remove it now. */ if (chan->cann_off >= map->map_size) { gossmap_remove_chan(map, chan); diff --git a/common/test/run-gossmap_local.c b/common/test/run-gossmap_local.c index 4debfc47c..376e4025e 100644 --- a/common/test/run-gossmap_local.c +++ b/common/test/run-gossmap_local.c @@ -333,7 +333,7 @@ int main(int argc, char *argv[]) char *gossfile; struct gossmap *map; struct node_id l1, l2, l3, l4; - struct short_channel_id scid23, scid12, scid_local; + struct short_channel_id scid23, scid12, scid_local, scid_nonexisting; struct gossmap_chan *chan; struct gossmap_localmods *mods; struct amount_sat capacity; @@ -498,6 +498,13 @@ int main(int argc, char *argv[]) AMOUNT_MSAT(100), 101, 102, 103, true, 0); + /* We can "update" a channel which doesn't exist, and it's a noop */ + scid_nonexisting.u64 = 1; + gossmap_local_updatechan(mods, scid_nonexisting, + AMOUNT_MSAT(1), + AMOUNT_MSAT(100000), + 2, 3, 4, false, 0); + gossmap_apply_localmods(map, mods); chan = gossmap_find_chan(map, &scid_local); assert(gossmap_chan_set(chan, 0)); @@ -510,6 +517,8 @@ int main(int argc, char *argv[]) assert(chan->half[0].proportional_fee == 3); assert(chan->half[0].delay == 4); + assert(!gossmap_find_chan(map, &scid_nonexisting)); + chan = gossmap_find_chan(map, &scid23); assert(chan->half[0].enabled); assert(chan->half[0].htlc_min == u64_to_fp16(99, false));