lightningd: consider old scids when looking up channels (for routing).
What changed, and why it matters
This commit fixes a routing bug in Core Lightning related to channel splicing. After a channel is spliced (a procedure that changes its identifying short-channel-id), the software previously refused to route payments using the old identifier for about six blocks, causing a temporary service gap. The fix makes the node also look up channels by their old identifiers, restoring routing continuity. There is no direct evidence this is a security vulnerability; it appears to be a protocol/routing reliability fix.
Treat as a normal reliability/protocol bug fix. Review whether the old_scids array is properly bounded and whether duplicate/old scids could introduce any ambiguity in routing decisions, but no immediate security response is indicated by the commit materials.
Security signals we found
Fixes a routing continuity failure after channel splicing
Changes lookup logic to include historical short-channel-ids
No input validation, memory safety, or cryptographic changes visible
No mention of security impact, CVE, or researcher attribution in commit
Evidence from the diff
The change modifies any_channel_by_scid() in lightningd/channel.c so that when a short-channel-id (scid) lookup fails against the current channel scid, it also iterates over chan->old_scids, returning the channel if any prior splice scid matches. The accompanying test test_route_by_old_scid is changed from an expected failure (xfail) to a network-conditional skip, reflecting that the behavior is now fixed on regtest. The changelog frames this as a protocol fix for a 6-block service gap after splicing.
Changed components
lightningd/channel.c:any_channel_by_scid()Lightning routing/gossip channel lookupSplicing-related channel state (old_scids)Inspect captured patch +7 / −1
diff --git a/lightningd/channel.c b/lightningd/channel.c
index e0377ac3..2ea68021 100644
--- a/lightningd/channel.c
+++ b/lightningd/channel.c
@@ -793,6 +793,12 @@ struct channel *any_channel_by_scid(struct lightningd *ld,
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;
diff --git a/tests/test_splicing.py b/tests/test_splicing.py
index 0a0747dd..79df7659 100644
--- a/tests/test_splicing.py
+++ b/tests/test_splicing.py
@@ -499,7 +499,7 @@ def test_splice_stuck_htlc(node_factory, bitcoind, executor):
assert l1.db_query("SELECT count(*) as c FROM channeltxs;")[0]['c'] == 0
-@pytest.mark.xfail(strict=True)
+@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
def test_route_by_old_scid(node_factory, bitcoind):
l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True, opts={'experimental-splicing': None})
Why this scored 32/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.