Skip to content

Commit be4de2b

Browse files
committed
Provide our peers with SCID aliases and forward payments with them
1 parent 828a6ea commit be4de2b

File tree

6 files changed

+199
-64
lines changed

6 files changed

+199
-64
lines changed

lightning/src/ln/channel.rs

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,11 @@ 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+
// We always offer our counterparty a static SCID alias, which we recognize as for this channel
706+
// if we see it in HTLC forwarding instructions. We don't bother rotating the alias given we
707+
// don't currently support node id aliases and eventually privacy should be provided with
708+
// blinded paths instead of simple scid+node_id aliases.
709+
outbound_scid_alias: u64,
705710
}
706711

707712
#[cfg(any(test, feature = "fuzztarget"))]
@@ -807,7 +812,8 @@ impl<Signer: Sign> Channel<Signer> {
807812
// Constructors:
808813
pub fn new_outbound<K: Deref, F: Deref>(
809814
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
815+
channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig, current_chain_height: u32,
816+
outbound_scid_alias: u64
811817
) -> Result<Channel<Signer>, APIError>
812818
where K::Target: KeysInterface<Signer = Signer>,
813819
F::Target: FeeEstimator,
@@ -955,6 +961,7 @@ impl<Signer: Sign> Channel<Signer> {
955961
workaround_lnd_bug_4006: None,
956962

957963
latest_inbound_scid_alias: None,
964+
outbound_scid_alias,
958965

959966
#[cfg(any(test, feature = "fuzztarget"))]
960967
historical_inbound_htlc_fulfills: HashSet::new(),
@@ -993,7 +1000,8 @@ impl<Signer: Sign> Channel<Signer> {
9931000
/// Assumes chain_hash has already been checked and corresponds with what we expect!
9941001
pub fn new_from_req<K: Deref, F: Deref, L: Deref>(
9951002
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
1003+
msg: &msgs::OpenChannel, user_id: u64, config: &UserConfig, current_chain_height: u32, logger: &L,
1004+
outbound_scid_alias: u64
9971005
) -> Result<Channel<Signer>, ChannelError>
9981006
where K::Target: KeysInterface<Signer = Signer>,
9991007
F::Target: FeeEstimator,
@@ -1262,6 +1270,7 @@ impl<Signer: Sign> Channel<Signer> {
12621270
workaround_lnd_bug_4006: None,
12631271

12641272
latest_inbound_scid_alias: None,
1273+
outbound_scid_alias,
12651274

12661275
#[cfg(any(test, feature = "fuzztarget"))]
12671276
historical_inbound_htlc_fulfills: HashSet::new(),
@@ -3467,7 +3476,7 @@ impl<Signer: Sign> Channel<Signer> {
34673476
Some(msgs::FundingLocked {
34683477
channel_id: self.channel_id(),
34693478
next_per_commitment_point,
3470-
short_channel_id_alias: None,
3479+
short_channel_id_alias: Some(self.outbound_scid_alias),
34713480
})
34723481
} else { None };
34733482

@@ -3689,7 +3698,7 @@ impl<Signer: Sign> Channel<Signer> {
36893698
funding_locked: Some(msgs::FundingLocked {
36903699
channel_id: self.channel_id(),
36913700
next_per_commitment_point,
3692-
short_channel_id_alias: None,
3701+
short_channel_id_alias: Some(self.outbound_scid_alias),
36933702
}),
36943703
raa: None, commitment_update: None, mon_update: None,
36953704
order: RAACommitmentOrder::CommitmentFirst,
@@ -3725,7 +3734,7 @@ impl<Signer: Sign> Channel<Signer> {
37253734
Some(msgs::FundingLocked {
37263735
channel_id: self.channel_id(),
37273736
next_per_commitment_point,
3728-
short_channel_id_alias: None,
3737+
short_channel_id_alias: Some(self.outbound_scid_alias),
37293738
})
37303739
} else { None };
37313740

@@ -4213,6 +4222,17 @@ impl<Signer: Sign> Channel<Signer> {
42134222
self.latest_inbound_scid_alias
42144223
}
42154224

4225+
/// Allowed in any state (including after shutdown)
4226+
pub fn get_outbound_scid_alias(&self) -> u64 {
4227+
self.outbound_scid_alias
4228+
}
4229+
/// Only allowed immediately after deserialization if get_outbound_scid_alias returns 0,
4230+
/// indicating we were written by an old LDK which did not set outbound SCID aliases.
4231+
pub fn set_outbound_scid_alias(&mut self, outbound_scid_alias: u64) {
4232+
assert_eq!(self.outbound_scid_alias, 0);
4233+
self.outbound_scid_alias = outbound_scid_alias;
4234+
}
4235+
42164236
/// Returns the funding_txo we either got from our peer, or were given by
42174237
/// get_outbound_funding_created.
42184238
pub fn get_funding_txo(&self) -> Option<OutPoint> {
@@ -4465,7 +4485,7 @@ impl<Signer: Sign> Channel<Signer> {
44654485
return Some(msgs::FundingLocked {
44664486
channel_id: self.channel_id,
44674487
next_per_commitment_point,
4468-
short_channel_id_alias: None,
4488+
short_channel_id_alias: Some(self.outbound_scid_alias),
44694489
});
44704490
}
44714491
} else {
@@ -5784,6 +5804,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
57845804
(15, preimages, vec_type),
57855805
(17, self.announcement_sigs_state, required),
57865806
(19, self.latest_inbound_scid_alias, option),
5807+
(21, self.outbound_scid_alias, required),
57875808
});
57885809

57895810
Ok(())
@@ -6040,6 +6061,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
60406061
// AnnouncementSignatures" which implies we'll re-send it on reconnect, but that's fine.
60416062
let mut announcement_sigs_state = Some(AnnouncementSigsState::NotSent);
60426063
let mut latest_inbound_scid_alias = None;
6064+
let mut outbound_scid_alias = None;
60436065

60446066
read_tlv_fields!(reader, {
60456067
(0, announcement_sigs, option),
@@ -6056,6 +6078,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
60566078
(15, preimages_opt, vec_type),
60576079
(17, announcement_sigs_state, option),
60586080
(19, latest_inbound_scid_alias, option),
6081+
(21, outbound_scid_alias, option),
60596082
});
60606083

60616084
if let Some(preimages) = preimages_opt {
@@ -6191,6 +6214,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
61916214
workaround_lnd_bug_4006: None,
61926215

61936216
latest_inbound_scid_alias,
6217+
// Later in the ChannelManager deserialization phase we scan for channels and assign scid aliases if its missing
6218+
outbound_scid_alias: outbound_scid_alias.unwrap_or(0),
61946219

61956220
#[cfg(any(test, feature = "fuzztarget"))]
61966221
historical_inbound_htlc_fulfills,
@@ -6314,7 +6339,7 @@ mod tests {
63146339
let secp_ctx = Secp256k1::new();
63156340
let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
63166341
let config = UserConfig::default();
6317-
match Channel::<EnforcingSigner>::new_outbound(&&fee_estimator, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0) {
6342+
match Channel::<EnforcingSigner>::new_outbound(&&fee_estimator, &&keys_provider, node_id, &features, 10000000, 100000, 42, &config, 0, 42) {
63186343
Err(APIError::IncompatibleShutdownScript { script }) => {
63196344
assert_eq!(script.into_inner(), non_v0_segwit_shutdown_script.into_inner());
63206345
},
@@ -6336,7 +6361,7 @@ mod tests {
63366361

63376362
let node_a_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
63386363
let config = UserConfig::default();
6339-
let node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_a_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
6364+
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();
63406365

63416366
// Now change the fee so we can check that the fee in the open_channel message is the
63426367
// same as the old fee.
@@ -6362,13 +6387,13 @@ mod tests {
63626387
// Create Node A's channel pointing to Node B's pubkey
63636388
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
63646389
let config = UserConfig::default();
6365-
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
6390+
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();
63666391

63676392
// Create Node B's channel by receiving Node A's open_channel message
63686393
// Make sure A's dust limit is as we expect.
63696394
let open_channel_msg = node_a_chan.get_open_channel(genesis_block(network).header.block_hash());
63706395
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
6371-
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();
6396+
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();
63726397

63736398
// Node B --> Node A: accept channel, explicitly setting B's dust limit.
63746399
let mut accept_channel_msg = node_b_chan.accept_inbound_channel();
@@ -6432,7 +6457,7 @@ mod tests {
64326457

64336458
let node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
64346459
let config = UserConfig::default();
6435-
let mut chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
6460+
let mut chan = Channel::<EnforcingSigner>::new_outbound(&&fee_est, &&keys_provider, node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0, 42).unwrap();
64366461

64376462
let commitment_tx_fee_0_htlcs = Channel::<EnforcingSigner>::commit_tx_fee_msat(chan.feerate_per_kw, 0, chan.opt_anchors());
64386463
let commitment_tx_fee_1_htlc = Channel::<EnforcingSigner>::commit_tx_fee_msat(chan.feerate_per_kw, 1, chan.opt_anchors());
@@ -6481,12 +6506,12 @@ mod tests {
64816506
// Create Node A's channel pointing to Node B's pubkey
64826507
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
64836508
let config = UserConfig::default();
6484-
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
6509+
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();
64856510

64866511
// Create Node B's channel by receiving Node A's open_channel message
64876512
let open_channel_msg = node_a_chan.get_open_channel(chain_hash);
64886513
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[7; 32]).unwrap());
6489-
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();
6514+
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();
64906515

64916516
// Node B --> Node A: accept channel
64926517
let accept_channel_msg = node_b_chan.accept_inbound_channel();
@@ -6543,7 +6568,7 @@ mod tests {
65436568
// Create a channel.
65446569
let node_b_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
65456570
let config = UserConfig::default();
6546-
let mut node_a_chan = Channel::<EnforcingSigner>::new_outbound(&&feeest, &&keys_provider, node_b_node_id, &InitFeatures::known(), 10000000, 100000, 42, &config, 0).unwrap();
6571+
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();
65476572
assert!(node_a_chan.counterparty_forwarding_info.is_none());
65486573
assert_eq!(node_a_chan.holder_htlc_minimum_msat, 1); // the default
65496574
assert!(node_a_chan.counterparty_forwarding_info().is_none());
@@ -6608,7 +6633,7 @@ mod tests {
66086633
let counterparty_node_id = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42; 32]).unwrap());
66096634
let mut config = UserConfig::default();
66106635
config.channel_options.announced_channel = false;
6611-
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
6636+
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
66126637
chan.holder_dust_limit_satoshis = 546;
66136638
chan.counterparty_selected_channel_reserve_satoshis = Some(0); // Filled in in accept_channel
66146639

0 commit comments

Comments
 (0)