Skip to content

Commit 638d48b

Browse files
committed
Track SCID aliases from our counterparty and use them in invoices
New `funding_locked` messages can include SCID aliases which our counterparty will recognize as "ours" for the purposes of relaying transactions to us. This avoids telling the world about our on-chain transactions every time we want to receive a payment, and will allow for receiving payments before the funding transaction appears on-chain. Here we store the new SCID aliases and use them in invoices instead of he "standard" SCIDs.
1 parent 384ff45 commit 638d48b

File tree

4 files changed

+48
-6
lines changed

4 files changed

+48
-6
lines changed

lightning-invoice/src/utils.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,11 @@ pub fn create_phantom_invoice<Signer: Sign, K: Deref>(
6565

6666
for hint in phantom_route_hints {
6767
for channel in &hint.channels {
68-
let short_channel_id = match channel.short_channel_id {
69-
Some(id) => id,
70-
None => continue,
68+
let short_channel_id = if let Some(scid) = channel.inbound_scid_alias { scid } else {
69+
match channel.short_channel_id {
70+
Some(id) => id,
71+
None => continue,
72+
}
7173
};
7274
let forwarding_info = match &channel.counterparty.forwarding_info {
7375
Some(info) => info.clone(),
@@ -162,9 +164,11 @@ where
162164
let our_channels = channelmanager.list_usable_channels();
163165
let mut route_hints = vec![];
164166
for channel in our_channels {
165-
let short_channel_id = match channel.short_channel_id {
166-
Some(id) => id,
167-
None => continue,
167+
let short_channel_id = if let Some(scid) = channel.inbound_scid_alias { scid } else {
168+
match channel.short_channel_id {
169+
Some(id) => id,
170+
None => continue,
171+
}
168172
};
169173
let forwarding_info = match channel.counterparty.forwarding_info {
170174
Some(info) => info,

lightning/src/ln/channel.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,13 @@ pub(super) struct Channel<Signer: Sign> {
695695

696696
/// This channel's type, as negotiated during channel open
697697
channel_type: ChannelTypeFeatures,
698+
699+
// Our counerparty can offer us SCID aliases which they will map to this channel when routing
700+
// outbound payments. These can be used in invoice route hints to provide privacy of which
701+
// on-chain transaction is ours.
702+
// We only bother storing the most recent SCID alias at any time, though our counterparty has
703+
// to store all of them.
704+
latest_inbound_scid_alias: Option<u64>,
698705
}
699706

700707
#[cfg(any(test, feature = "fuzztarget"))]
@@ -947,6 +954,8 @@ impl<Signer: Sign> Channel<Signer> {
947954

948955
workaround_lnd_bug_4006: None,
949956

957+
latest_inbound_scid_alias: None,
958+
950959
#[cfg(any(test, feature = "fuzztarget"))]
951960
historical_inbound_htlc_fulfills: HashSet::new(),
952961

@@ -1252,6 +1261,8 @@ impl<Signer: Sign> Channel<Signer> {
12521261

12531262
workaround_lnd_bug_4006: None,
12541263

1264+
latest_inbound_scid_alias: None,
1265+
12551266
#[cfg(any(test, feature = "fuzztarget"))]
12561267
historical_inbound_htlc_fulfills: HashSet::new(),
12571268

@@ -2141,6 +2152,15 @@ impl<Signer: Sign> Channel<Signer> {
21412152
return Err(ChannelError::Ignore("Peer sent funding_locked when we needed a channel_reestablish. The peer is likely lnd, see https://github.com/lightningnetwork/lnd/issues/4006".to_owned()));
21422153
}
21432154

2155+
if let Some(scid_alias) = msg.short_channel_id_alias {
2156+
if Some(scid_alias) != self.short_channel_id {
2157+
// The scid alias provided can be used to route payments *from* our counterparty,
2158+
// i.e. can be used for inbound payments and provided in invoices, but is not used
2159+
// whrn routing outbound payments.
2160+
self.latest_inbound_scid_alias = Some(scid_alias);
2161+
}
2162+
}
2163+
21442164
let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
21452165

21462166
if non_shutdown_state == ChannelState::FundingSent as u32 {
@@ -4188,6 +4208,11 @@ impl<Signer: Sign> Channel<Signer> {
41884208
self.short_channel_id
41894209
}
41904210

4211+
/// Allowed in any state (including after shutdown)
4212+
pub fn get_latest_inbound_scid_alias(&self) -> Option<u64> {
4213+
self.latest_inbound_scid_alias
4214+
}
4215+
41914216
/// Returns the funding_txo we either got from our peer, or were given by
41924217
/// get_outbound_funding_created.
41934218
pub fn get_funding_txo(&self) -> Option<OutPoint> {
@@ -5758,6 +5783,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
57585783
(13, self.channel_creation_height, required),
57595784
(15, preimages, vec_type),
57605785
(17, self.announcement_sigs_state, required),
5786+
(19, self.latest_inbound_scid_alias, option),
57615787
});
57625788

57635789
Ok(())
@@ -6013,6 +6039,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
60136039
// If we read an old Channel, for simplicity we just treat it as "we never sent an
60146040
// AnnouncementSignatures" which implies we'll re-send it on reconnect, but that's fine.
60156041
let mut announcement_sigs_state = Some(AnnouncementSigsState::NotSent);
6042+
let mut latest_inbound_scid_alias = None;
60166043

60176044
read_tlv_fields!(reader, {
60186045
(0, announcement_sigs, option),
@@ -6028,6 +6055,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
60286055
(13, channel_creation_height, option),
60296056
(15, preimages_opt, vec_type),
60306057
(17, announcement_sigs_state, option),
6058+
(19, latest_inbound_scid_alias, option),
60316059
});
60326060

60336061
if let Some(preimages) = preimages_opt {
@@ -6162,6 +6190,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
61626190

61636191
workaround_lnd_bug_4006: None,
61646192

6193+
latest_inbound_scid_alias,
6194+
61656195
#[cfg(any(test, feature = "fuzztarget"))]
61666196
historical_inbound_htlc_fulfills,
61676197

lightning/src/ln/channelmanager.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,11 @@ pub struct ChannelDetails {
11871187
/// The position of the funding transaction in the chain. None if the funding transaction has
11881188
/// not yet been confirmed and the channel fully opened.
11891189
pub short_channel_id: Option<u64>,
1190+
/// An optional [`short_channel_id`] alias for this channel, randomly generated by our
1191+
/// counterparty and usable in place of [`short_channel_id`] in invoice route hints. Our
1192+
/// counterparty will recognize the alias provided here in place of the [`short_channel_id`]
1193+
/// when they see a payment to be routed to us.
1194+
pub inbound_scid_alias: Option<u64>,
11901195
/// The value, in satoshis, of this channel as appears in the funding output
11911196
pub channel_value_satoshis: u64,
11921197
/// The value, in satoshis, that must always be held in the channel for us. This value ensures
@@ -1830,6 +1835,7 @@ impl<Signer: Sign, M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelMana
18301835
},
18311836
funding_txo: channel.get_funding_txo(),
18321837
short_channel_id: channel.get_short_channel_id(),
1838+
inbound_scid_alias: channel.get_latest_inbound_scid_alias(),
18331839
channel_value_satoshis: channel.get_value_satoshis(),
18341840
unspendable_punishment_reserve: to_self_reserve_satoshis,
18351841
balance_msat,
@@ -5955,6 +5961,7 @@ impl_writeable_tlv_based!(ChannelCounterparty, {
59555961
});
59565962

59575963
impl_writeable_tlv_based!(ChannelDetails, {
5964+
(1, inbound_scid_alias, option),
59585965
(2, channel_id, required),
59595966
(4, counterparty, required),
59605967
(6, funding_txo, option),

lightning/src/routing/router.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,6 +1563,7 @@ mod tests {
15631563
},
15641564
funding_txo: Some(OutPoint { txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(), index: 0 }),
15651565
short_channel_id,
1566+
inbound_scid_alias: None,
15661567
channel_value_satoshis: 0,
15671568
user_channel_id: 0,
15681569
balance_msat: 0,

0 commit comments

Comments
 (0)