Skip to content

Commit 84fa127

Browse files
committed
Provide our peers with SCID aliases and forward payments with them
This creates an SCID alias for all of our outbound channels, which we send to our counterparties as a part of the `funding_locked` message and then recognize in any HTLC forwarding instructions. Note that we generate an SCID alias for all channels, including already open ones, even though we currently have no way of communicating to our peers the SCID alias for already-open channels.
1 parent 10be993 commit 84fa127

7 files changed

+236
-70
lines changed

lightning/src/ln/channel.rs

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,12 @@ pub(super) struct Channel<Signer: Sign> {
702702
// We only bother storing the most recent SCID alias at any time, though our counterparty has
703703
// to store all of them.
704704
latest_inbound_scid_alias: Option<u64>,
705+
706+
// We always offer our counterparty a static SCID alias, which we recognize as for this channel
707+
// if we see it in HTLC forwarding instructions. We don't bother rotating the alias given we
708+
// don't currently support node id aliases and eventually privacy should be provided with
709+
// blinded paths instead of simple scid+node_id aliases.
710+
outbound_scid_alias: u64,
705711
}
706712

707713
#[cfg(any(test, fuzzing))]
@@ -807,7 +813,8 @@ impl<Signer: Sign> Channel<Signer> {
807813
// Constructors:
808814
pub fn new_outbound<K: Deref, F: Deref>(
809815
fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
810-
channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig, current_chain_height: u32
816+
channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig, current_chain_height: u32,
817+
outbound_scid_alias: u64
811818
) -> Result<Channel<Signer>, APIError>
812819
where K::Target: KeysInterface<Signer = Signer>,
813820
F::Target: FeeEstimator,
@@ -955,6 +962,7 @@ impl<Signer: Sign> Channel<Signer> {
955962
workaround_lnd_bug_4006: None,
956963

957964
latest_inbound_scid_alias: None,
965+
outbound_scid_alias,
958966

959967
#[cfg(any(test, fuzzing))]
960968
historical_inbound_htlc_fulfills: HashSet::new(),
@@ -993,7 +1001,8 @@ impl<Signer: Sign> Channel<Signer> {
9931001
/// Assumes chain_hash has already been checked and corresponds with what we expect!
9941002
pub fn new_from_req<K: Deref, F: Deref, L: Deref>(
9951003
fee_estimator: &F, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
996-
msg: &msgs::OpenChannel, user_id: u64, config: &UserConfig, current_chain_height: u32, logger: &L
1004+
msg: &msgs::OpenChannel, user_id: u64, config: &UserConfig, current_chain_height: u32, logger: &L,
1005+
outbound_scid_alias: u64
9971006
) -> Result<Channel<Signer>, ChannelError>
9981007
where K::Target: KeysInterface<Signer = Signer>,
9991008
F::Target: FeeEstimator,
@@ -1262,6 +1271,7 @@ impl<Signer: Sign> Channel<Signer> {
12621271
workaround_lnd_bug_4006: None,
12631272

12641273
latest_inbound_scid_alias: None,
1274+
outbound_scid_alias,
12651275

12661276
#[cfg(any(test, fuzzing))]
12671277
historical_inbound_htlc_fulfills: HashSet::new(),
@@ -3477,7 +3487,7 @@ impl<Signer: Sign> Channel<Signer> {
34773487
Some(msgs::FundingLocked {
34783488
channel_id: self.channel_id(),
34793489
next_per_commitment_point,
3480-
short_channel_id_alias: None,
3490+
short_channel_id_alias: Some(self.outbound_scid_alias),
34813491
})
34823492
} else { None };
34833493

@@ -3699,7 +3709,7 @@ impl<Signer: Sign> Channel<Signer> {
36993709
funding_locked: Some(msgs::FundingLocked {
37003710
channel_id: self.channel_id(),
37013711
next_per_commitment_point,
3702-
short_channel_id_alias: None,
3712+
short_channel_id_alias: Some(self.outbound_scid_alias),
37033713
}),
37043714
raa: None, commitment_update: None, mon_update: None,
37053715
order: RAACommitmentOrder::CommitmentFirst,
@@ -3735,7 +3745,7 @@ impl<Signer: Sign> Channel<Signer> {
37353745
Some(msgs::FundingLocked {
37363746
channel_id: self.channel_id(),
37373747
next_per_commitment_point,
3738-
short_channel_id_alias: None,
3748+
short_channel_id_alias: Some(self.outbound_scid_alias),
37393749
})
37403750
} else { None };
37413751

@@ -4223,6 +4233,17 @@ impl<Signer: Sign> Channel<Signer> {
42234233
self.latest_inbound_scid_alias
42244234
}
42254235

4236+
/// Allowed in any state (including after shutdown)
4237+
pub fn outbound_scid_alias(&self) -> u64 {
4238+
self.outbound_scid_alias
4239+
}
4240+
/// Only allowed immediately after deserialization if get_outbound_scid_alias returns 0,
4241+
/// indicating we were written by an old LDK which did not set outbound SCID aliases.
4242+
pub fn set_outbound_scid_alias(&mut self, outbound_scid_alias: u64) {
4243+
assert_eq!(self.outbound_scid_alias, 0);
4244+
self.outbound_scid_alias = outbound_scid_alias;
4245+
}
4246+
42264247
/// Returns the funding_txo we either got from our peer, or were given by
42274248
/// get_outbound_funding_created.
42284249
pub fn get_funding_txo(&self) -> Option<OutPoint> {
@@ -4475,7 +4496,7 @@ impl<Signer: Sign> Channel<Signer> {
44754496
return Some(msgs::FundingLocked {
44764497
channel_id: self.channel_id,
44774498
next_per_commitment_point,
4478-
short_channel_id_alias: None,
4499+
short_channel_id_alias: Some(self.outbound_scid_alias),
44794500
});
44804501
}
44814502
} else {
@@ -5795,6 +5816,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
57955816
(15, preimages, vec_type),
57965817
(17, self.announcement_sigs_state, required),
57975818
(19, self.latest_inbound_scid_alias, option),
5819+
(21, self.outbound_scid_alias, required),
57985820
});
57995821

58005822
Ok(())
@@ -6051,6 +6073,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
60516073
// AnnouncementSignatures" which implies we'll re-send it on reconnect, but that's fine.
60526074
let mut announcement_sigs_state = Some(AnnouncementSigsState::NotSent);
60536075
let mut latest_inbound_scid_alias = None;
6076+
let mut outbound_scid_alias = None;
60546077

60556078
read_tlv_fields!(reader, {
60566079
(0, announcement_sigs, option),
@@ -6067,6 +6090,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
60676090
(15, preimages_opt, vec_type),
60686091
(17, announcement_sigs_state, option),
60696092
(19, latest_inbound_scid_alias, option),
6093+
(21, outbound_scid_alias, option),
60706094
});
60716095

60726096
if let Some(preimages) = preimages_opt {
@@ -6202,6 +6226,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
62026226
workaround_lnd_bug_4006: None,
62036227

62046228
latest_inbound_scid_alias,
6229+
// Later in the ChannelManager deserialization phase we scan for channels and assign scid aliases if its missing
6230+
outbound_scid_alias: outbound_scid_alias.unwrap_or(0),
62056231

62066232
#[cfg(any(test, fuzzing))]
62076233
historical_inbound_htlc_fulfills,
@@ -6325,7 +6351,7 @@ mod tests {
63256351
let secp_ctx = Secp256k1::new();
63266352
let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
63276353
let config = UserConfig::default();
6328-
match Channel::<EnforcingSigner>::new_outbound(&&fee_estimator, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0) {
6354+
match Channel::<EnforcingSigner>::new_outbound(&&fee_estimator, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0, 42) {
63296355
Err(APIError::IncompatibleShutdownScript { script }) => {
63306356
assert_eq!(script.into_inner(), non_v0_segwit_shutdown_script.into_inner());
63316357
},
@@ -6347,7 +6373,7 @@ mod tests {
63476373

63486374
let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
63496375
let config = UserConfig::default();
6350-
let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_a_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
6376+
let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_a_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0, 42).unwrap();
63516377

63526378
// Now change the fee so we can check that the fee in the open_channel message is the
63536379
// same as the old fee.
@@ -6373,13 +6399,13 @@ mod tests {
63736399
// Create Node A's channel pointing to Node B's pubkey
63746400
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
63756401
let config = UserConfig::default();
6376-
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
6402+
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0, 42).unwrap();
63776403

63786404
// Create Node B's channel by receiving Node A's open_channel message
63796405
// Make sure A's dust limit is as we expect.
63806406
let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
63816407
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
6382-
let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0, &&logger).unwrap();
6408+
let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0, &&logger, 42).unwrap();
63836409

63846410
// Node B --> Node A: accept channel, explicitly setting B's dust limit.
63856411
let mut accept_channel_msg = node_b_chan.accept_inbound_channel();
@@ -6443,7 +6469,7 @@ mod tests {
64436469

64446470
let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
64456471
let config = UserConfig::default();
6446-
let mut chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
6472+
let mut chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0, 42).unwrap();
64476473

64486474
let commitment_tx_fee_0_htlcs = Channel::<EnforcingSigner>::commit_tx_fee_msat(chan.feerate_per_kw, 0, chan.opt_anchors());
64496475
let commitment_tx_fee_1_htlc = Channel::<EnforcingSigner>::commit_tx_fee_msat(chan.feerate_per_kw, 1, chan.opt_anchors());
@@ -6492,12 +6518,12 @@ mod tests {
64926518
// Create Node A's channel pointing to Node B's pubkey
64936519
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
64946520
let config = UserConfig::default();
6495-
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
6521+
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0, 42).unwrap();
64966522

64976523
// Create Node B's channel by receiving Node A's open_channel message
64986524
let open_channel_msg = node_a_chan.get_open_channel(chain_hash);
64996525
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
6500-
let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0, &&logger).unwrap();
6526+
let mut node_b_chan = Channel::<EnforcingSigner>::new_from_req(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), &open_channel_msg, 7, &config, 0, &&logger, 42).unwrap();
65016527

65026528
// Node B --> Node A: accept channel
65036529
let accept_channel_msg = node_b_chan.accept_inbound_channel();
@@ -6554,7 +6580,7 @@ mod tests {
65546580
// Create a channel.
65556581
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
65566582
let config = UserConfig::default();
6557-
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
6583+
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0, 42).unwrap();
65586584
assert!(node_a_chan.counterparty_forwarding_info.is_none());
65596585
assert_eq!(node_a_chan.holder_htlc_minimum_msat, 1); // the default
65606586
assert!(node_a_chan.counterparty_forwarding_info().is_none());
@@ -6619,7 +6645,7 @@ mod tests {
66196645
let counterparty_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
66206646
let mut config = UserConfig::default();
66216647
config.channel_options.announced_channel = false;
6622-
let mut chan = Channel::<InMemorySigner>::new_outbound(&&feeest, &&keys_provider, counterparty_node_id, &InitFeatures::known(), 10_000_000, 100000, 42, &config, 0).unwrap(); // Nothing uses their network key in this test
6648+
let mut chan = Channel::<InMemorySigner>::new_outbound(&&feeest, &&keys_provider, counterparty_node_id, &InitFeatures::known(), 10_000_000, 100000, 42, &config, 0, 42).unwrap(); // Nothing uses their network key in this test
66236649
chan.holder_dust_limit_satoshis = 546;
66246650
chan.counterparty_selected_channel_reserve_satoshis = Some(0); // Filled in in accept_channel
66256651

0 commit comments

Comments
 (0)