connectd: don't be That Node when someone is gossipping crap.
What changed, and why it matters
This change is a minor log/noise reduction fix. When a peer sends a channel announcement for a channel whose funding transaction output has already been spent, the node used to send a warning message back every single time. Now it sends that warning at most once per second. The old behavior could annoy or overload peers (especially older CLN versions that keep sending stale announcements), but it does not create a direct security vulnerability like theft or remote crash.
No urgent action. Treat as routine maintenance. Operators may notice reduced warning log volume from peers running old CLN versions.
Security signals we found
Rate-limiting of peer warning messages
Log/DoS noise reduction from stale gossip
No cryptographic or authorization change
Evidence from the diff
In gossipd/gossmap_manage.c, the handler for a channel_announcement with an already-spent UTXO (tal_count(outscript) == 0) previously called peer_warning() unconditionally. The patch adds a one-second rate limit using a static timemono variable, so peer_warning() is only emitted if more than one second has passed since the last warning. This addresses observed log spam from pre-25.12 CLN nodes that gossip stale channel announcements. The functional handling of the bad announcement (goto bad) is unchanged.
Changed components
gossipd/gossmap_manage.cconnectd peer warning pathInspect captured patch +10 / −3
diff --git a/gossipd/gossmap_manage.c b/gossipd/gossmap_manage.c
index c0589148..556104c7 100644
--- a/gossipd/gossmap_manage.c
+++ b/gossipd/gossmap_manage.c
@@ -703,9 +703,16 @@ void gossmap_manage_handle_get_txout_reply(struct gossmap_manage *gm, const u8 *
* - MUST ignore the message.
*/
if (tal_count(outscript) == 0) {
- peer_warning(gm, pca->source_peer,
- "channel_announcement: no unspent txout %s",
- fmt_short_channel_id(tmpctx, scid));
+ /* Don't flood them: this happens with pre-25.12 CLN
+ * nodes, which lost their marbles about some old
+ * UTXOs. */
+ static struct timemono prev;
+ if (time_greater(timemono_since(prev), time_from_sec(1))) {
+ peer_warning(gm, pca->source_peer,
+ "channel_announcement: no unspent txout %s",
+ fmt_short_channel_id(tmpctx, scid));
+ prev = time_mono();
+ }
goto bad;
}
Why this scored 23/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.