gossipd: use gossmap to load the dying entries.
What changed, and why it matters
This is a small internal refactoring change in Core Lightning's gossip subsystem. It changes how 'dying' channel entries are loaded from the gossip store, switching from one temporary array to a callback that populates a persistent list. There is no indication this fixes a security bug or introduces a vulnerability; it appears to be code cleanup.
No security action required. Treat as routine refactoring. Reviewers may want to confirm the FIXME regarding tal_free(dying) is addressed in a follow-up, as it suggests the temporary allocation is now unnecessary.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors setup_gossmap() in gossipd/gossmap_manage.c. Previously, gossip_store_new() returned a temporary ‘dying’ array which was then passed to gossmap_load_initial(). Now, a callback (gossmap_add_dying_chan) is registered with gossmap_load_initial() to add dying channels directly to gm->dying_channels. The temporary ‘dying’ pointer is allocated by gossip_store_new(), immediately freed with a FIXME comment, and no longer used. The gossmap_logcb signature is also corrected to take struct gossmap_manage gm instead of struct daemon daemon. No security-relevant behavior change is evident from the diff.
Changed components
gossipd/gossmap_manage.cgossip store initializationdying channel trackingInspect captured patch +24 / −9
diff --git a/gossipd/gossmap_manage.c b/gossipd/gossmap_manage.c
index cc4c6264..6260673a 100644
--- a/gossipd/gossmap_manage.c
+++ b/gossipd/gossmap_manage.c
@@ -430,7 +430,7 @@ static void start_prune_timer(struct gossmap_manage *gm)
static void reprocess_queued_msgs(struct gossmap_manage *gm);
-static void gossmap_logcb(struct daemon *daemon,
+static void gossmap_logcb(struct gossmap_manage *gm,
enum log_level level,
const char *fmt,
...)
@@ -442,31 +442,46 @@ static void gossmap_logcb(struct daemon *daemon,
va_end(ap);
}
+static void gossmap_add_dying_chan(struct short_channel_id scid,
+ u32 blockheight,
+ u64 offset,
+ struct gossmap_manage *gm)
+{
+ struct chan_dying cd;
+
+ cd.scid = scid;
+ cd.deadline = blockheight;
+ cd.gossmap_offset = offset;
+ tal_arr_expand(&gm->dying_channels, cd);
+}
+
static bool setup_gossmap(struct gossmap_manage *gm,
- struct daemon *daemon,
- struct chan_dying **dying)
+ struct daemon *daemon)
{
u64 expected_len;
+ struct chan_dying *dying = NULL;
- *dying = NULL;
+ gm->dying_channels = tal_arr(gm, struct chan_dying, 0);
/* This does simple sanitry checks, compacts, and creates if
* necessary */
gm->gs = gossip_store_new(gm,
daemon,
&gm->gossip_store_populated,
- dying);
+ &dying);
if (!gm->gs)
return false;
+ /* FIXME: Remove */
+ tal_free(dying);
expected_len = gossip_store_len_written(gm->gs);
/* This actually loads it into memory, with strict checks. */
gm->raw_gossmap = gossmap_load_initial(gm, GOSSIP_STORE_FILENAME,
expected_len,
gossmap_logcb,
- NULL,
- daemon);
+ gossmap_add_dying_chan,
+ gm);
if (!gm->raw_gossmap) {
gm->gs = tal_free(gm->gs);
return false;
@@ -487,10 +502,10 @@ struct gossmap_manage *gossmap_manage_new(const tal_t *ctx,
{
struct gossmap_manage *gm = tal(ctx, struct gossmap_manage);
- if (!setup_gossmap(gm, daemon, &gm->dying_channels)) {
+ if (!setup_gossmap(gm, daemon)) {
tal_free(gm->dying_channels);
gossip_store_corrupt();
- if (!setup_gossmap(gm, daemon, &gm->dying_channels))
+ if (!setup_gossmap(gm, daemon))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Could not re-initialize %s", GOSSIP_STORE_FILENAME);
}
Why this scored 11/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.