wallet: don't show htlcs from closed channels in listhtlcs.
What changed, and why it matters
This is a small, forward-looking cleanup change in Core Lightning's wallet code. It adjusts a database query so that the `listhtlcs` command will not return HTLCs (payment forwarding contracts) belonging to channels that have already been closed. The commit explicitly says this situation cannot happen yet because HTLCs are currently deleted when a channel closes, but the code is being prepared for an upcoming change where closed-channel HTLCs may be kept around.
No immediate action required. Treat as routine hardening. If the upcoming HTLC-retention change is being reviewed, verify that all other HTLC consumers (not just `listhtlcs`) correctly handle or exclude closed-channel HTLCs.
Security signals we found
Information-disclosure hardening: prevents future exposure of stale HTLC data from closed channels
Defensive query filter added to database iterator used by RPC output
No active vulnerability described; commit frames change as future-proofing
Evidence from the diff
The patch modifies wallet_htlcs_first() in wallet/wallet.c to add WHERE channels.state != CLOSED to both HTLC-listing SQL queries and binds the closed channel state parameter. This filters out HTLCs associated with closed channels before returning results to callers such as listhtlcs. The change is defensive/preparatory and not a fix for an active bug.
Changed components
wallet/wallet.cwallet_htlcs_first()listhtlcs RPC data pathInspect captured patch +5 / −2
diff --git a/wallet/wallet.c b/wallet/wallet.c
index ddc933d7..1c7ad233 100644
--- a/wallet/wallet.c
+++ b/wallet/wallet.c
@@ -6558,7 +6558,8 @@ struct wallet_htlc_iter *wallet_htlcs_first(const tal_t *ctx,
", h.updated_index"
" FROM channel_htlcs h"
" JOIN channels ON channels.id = h.channel_id"
- " WHERE h.updated_index >= ?"
+ " WHERE channels.state != ?"
+ " AND h.updated_index >= ?"
" ORDER BY h.updated_index ASC"
" LIMIT ?;"));
} else {
@@ -6575,10 +6576,12 @@ struct wallet_htlc_iter *wallet_htlcs_first(const tal_t *ctx,
", h.updated_index"
" FROM channel_htlcs h"
" JOIN channels ON channels.id = h.channel_id"
- " WHERE h.id >= ?"
+ " WHERE channels.state != ?"
+ " AND h.id >= ?"
" ORDER BY h.id ASC"
" LIMIT ?;"));
}
+ db_bind_int(i->stmt, channel_state_in_db(CLOSED));
}
db_bind_u64(i->stmt, liststart);
if (listlimit)
Why this scored 18/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.