lightningd: use the hash table to lookup scids.
What changed, and why it matters
This is a performance improvement that replaces a slow search through every peer and channel with a fast hash table lookup when finding a channel by its short channel ID. The commit message and code show the same privacy rules were preserved. There is no security bug being fixed here.
No security action required. Treat as a normal performance refactor; review that the hash table is populated with aliases and old scids as expected.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The function any_channel_by_scid previously iterated every peer and every channel to find a match by scid, alias, or old scid. The patch changes it to use channel_scid_map_get on ld->channels_by_scid. The privacy logic (always allow alias lookup; reject real scid lookups for OPT_SCID_ALIAS channels unless privacy_leak_ok) is retained, though the old_scids loop is removed because the hash table is expected to contain those mappings already.
Changed components
lightningd/channel.c:any_channel_by_scidInspect captured patch +22 / −37
diff --git a/lightningd/channel.c b/lightningd/channel.c
index b6e9593e..d69865b2 100644
--- a/lightningd/channel.c
+++ b/lightningd/channel.c
@@ -816,43 +816,28 @@ struct channel *any_channel_by_scid(struct lightningd *ld,
struct short_channel_id scid,
bool privacy_leak_ok)
{
- struct peer *p;
- struct channel *chan;
- struct peer_node_id_map_iter it;
-
- /* FIXME: Support lookup by scid directly! */
- for (p = peer_node_id_map_first(ld->peers, &it);
- p;
- p = peer_node_id_map_next(ld->peers, &it)) {
- list_for_each(&p->channels, chan, list) {
- /* BOLT #2:
- * - MUST always recognize the `alias` as a
- * `short_channel_id` for incoming HTLCs to this
- * channel.
- */
- if (chan->alias[LOCAL] &&
- short_channel_id_eq(scid, *chan->alias[LOCAL]))
- return chan;
- /* BOLT #2:
- * - if `channel_type` has `option_scid_alias` set:
- * - MUST NOT allow incoming HTLCs to this channel
- * using the real `short_channel_id`
- */
- if (!privacy_leak_ok
- && channel_type_has(chan->type, OPT_SCID_ALIAS))
- continue;
- if (chan->scid
- && short_channel_id_eq(scid, *chan->scid))
- return chan;
-
- /* Look through any old pre-splice channel ids */
- for (size_t i = 0; i < tal_count(chan->old_scids); i++) {
- if (short_channel_id_eq(scid, chan->old_scids[i]))
- return chan;
- }
- }
- }
- return NULL;
+ const struct scid_to_channel *scc = channel_scid_map_get(ld->channels_by_scid, scid);
+ if (!scc)
+ return NULL;
+
+ /* BOLT #2:
+ * - MUST always recognize the `alias` as a `short_channel_id` for
+ * incoming HTLCs to this channel.
+ */
+ if (scc->channel->alias[LOCAL]
+ && short_channel_id_eq(scid, *scc->channel->alias[LOCAL]))
+ return scc->channel;
+
+ /* BOLT #2:
+ * - if `channel_type` has `option_scid_alias` set:
+ * - MUST NOT allow incoming HTLCs to this channel using the real
+ * `short_channel_id`
+ */
+ /* This means any scids other than the alias (handled above) cannot be exposed */
+ if (!privacy_leak_ok && channel_type_has(scc->channel->type, OPT_SCID_ALIAS))
+ return NULL;
+
+ return scc->channel;
}
struct channel *channel_by_dbid(struct lightningd *ld, const u64 dbid)
Why this scored 12/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.