@@ -702,6 +702,11 @@ pub(super) struct Channel<Signer: Sign> {
702
702
// We only bother storing the most recent SCID alias at any time, though our counterparty has
703
703
// to store all of them.
704
704
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 ,
705
710
}
706
711
707
712
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
@@ -807,7 +812,8 @@ impl<Signer: Sign> Channel<Signer> {
807
812
// Constructors:
808
813
pub fn new_outbound < K : Deref , F : Deref > (
809
814
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
811
817
) -> Result < Channel < Signer > , APIError >
812
818
where K :: Target : KeysInterface < Signer = Signer > ,
813
819
F :: Target : FeeEstimator ,
@@ -955,6 +961,7 @@ impl<Signer: Sign> Channel<Signer> {
955
961
workaround_lnd_bug_4006 : None ,
956
962
957
963
latest_inbound_scid_alias : None ,
964
+ outbound_scid_alias,
958
965
959
966
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
960
967
historical_inbound_htlc_fulfills : HashSet :: new ( ) ,
@@ -993,7 +1000,8 @@ impl<Signer: Sign> Channel<Signer> {
993
1000
/// Assumes chain_hash has already been checked and corresponds with what we expect!
994
1001
pub fn new_from_req < K : Deref , F : Deref , L : Deref > (
995
1002
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
997
1005
) -> Result < Channel < Signer > , ChannelError >
998
1006
where K :: Target : KeysInterface < Signer = Signer > ,
999
1007
F :: Target : FeeEstimator ,
@@ -1262,6 +1270,7 @@ impl<Signer: Sign> Channel<Signer> {
1262
1270
workaround_lnd_bug_4006 : None ,
1263
1271
1264
1272
latest_inbound_scid_alias : None ,
1273
+ outbound_scid_alias,
1265
1274
1266
1275
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
1267
1276
historical_inbound_htlc_fulfills : HashSet :: new ( ) ,
@@ -3467,7 +3476,7 @@ impl<Signer: Sign> Channel<Signer> {
3467
3476
Some ( msgs:: FundingLocked {
3468
3477
channel_id : self . channel_id ( ) ,
3469
3478
next_per_commitment_point,
3470
- short_channel_id_alias : None ,
3479
+ short_channel_id_alias : Some ( self . outbound_scid_alias ) ,
3471
3480
} )
3472
3481
} else { None } ;
3473
3482
@@ -3689,7 +3698,7 @@ impl<Signer: Sign> Channel<Signer> {
3689
3698
funding_locked : Some ( msgs:: FundingLocked {
3690
3699
channel_id : self . channel_id ( ) ,
3691
3700
next_per_commitment_point,
3692
- short_channel_id_alias : None ,
3701
+ short_channel_id_alias : Some ( self . outbound_scid_alias ) ,
3693
3702
} ) ,
3694
3703
raa : None , commitment_update : None , mon_update : None ,
3695
3704
order : RAACommitmentOrder :: CommitmentFirst ,
@@ -3725,7 +3734,7 @@ impl<Signer: Sign> Channel<Signer> {
3725
3734
Some ( msgs:: FundingLocked {
3726
3735
channel_id : self . channel_id ( ) ,
3727
3736
next_per_commitment_point,
3728
- short_channel_id_alias : None ,
3737
+ short_channel_id_alias : Some ( self . outbound_scid_alias ) ,
3729
3738
} )
3730
3739
} else { None } ;
3731
3740
@@ -4213,6 +4222,17 @@ impl<Signer: Sign> Channel<Signer> {
4213
4222
self . latest_inbound_scid_alias
4214
4223
}
4215
4224
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
+
4216
4236
/// Returns the funding_txo we either got from our peer, or were given by
4217
4237
/// get_outbound_funding_created.
4218
4238
pub fn get_funding_txo ( & self ) -> Option < OutPoint > {
@@ -4465,7 +4485,7 @@ impl<Signer: Sign> Channel<Signer> {
4465
4485
return Some ( msgs:: FundingLocked {
4466
4486
channel_id : self . channel_id ,
4467
4487
next_per_commitment_point,
4468
- short_channel_id_alias : None ,
4488
+ short_channel_id_alias : Some ( self . outbound_scid_alias ) ,
4469
4489
} ) ;
4470
4490
}
4471
4491
} else {
@@ -5784,6 +5804,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
5784
5804
( 15 , preimages, vec_type) ,
5785
5805
( 17 , self . announcement_sigs_state, required) ,
5786
5806
( 19 , self . latest_inbound_scid_alias, option) ,
5807
+ ( 21 , self . outbound_scid_alias, required) ,
5787
5808
} ) ;
5788
5809
5789
5810
Ok ( ( ) )
@@ -6040,6 +6061,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
6040
6061
// AnnouncementSignatures" which implies we'll re-send it on reconnect, but that's fine.
6041
6062
let mut announcement_sigs_state = Some ( AnnouncementSigsState :: NotSent ) ;
6042
6063
let mut latest_inbound_scid_alias = None ;
6064
+ let mut outbound_scid_alias = None ;
6043
6065
6044
6066
read_tlv_fields ! ( reader, {
6045
6067
( 0 , announcement_sigs, option) ,
@@ -6056,6 +6078,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
6056
6078
( 15 , preimages_opt, vec_type) ,
6057
6079
( 17 , announcement_sigs_state, option) ,
6058
6080
( 19 , latest_inbound_scid_alias, option) ,
6081
+ ( 21 , outbound_scid_alias, option) ,
6059
6082
} ) ;
6060
6083
6061
6084
if let Some ( preimages) = preimages_opt {
@@ -6191,6 +6214,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
6191
6214
workaround_lnd_bug_4006 : None ,
6192
6215
6193
6216
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 ) ,
6194
6219
6195
6220
#[ cfg( any( test, feature = "fuzztarget" ) ) ]
6196
6221
historical_inbound_htlc_fulfills,
@@ -6314,7 +6339,7 @@ mod tests {
6314
6339
let secp_ctx = Secp256k1 :: new ( ) ;
6315
6340
let node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6316
6341
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 ) {
6318
6343
Err ( APIError :: IncompatibleShutdownScript { script } ) => {
6319
6344
assert_eq ! ( script. into_inner( ) , non_v0_segwit_shutdown_script. into_inner( ) ) ;
6320
6345
} ,
@@ -6336,7 +6361,7 @@ mod tests {
6336
6361
6337
6362
let node_a_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6338
6363
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 ( ) ;
6340
6365
6341
6366
// Now change the fee so we can check that the fee in the open_channel message is the
6342
6367
// same as the old fee.
@@ -6362,13 +6387,13 @@ mod tests {
6362
6387
// Create Node A's channel pointing to Node B's pubkey
6363
6388
let node_b_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6364
6389
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 ( ) ;
6366
6391
6367
6392
// Create Node B's channel by receiving Node A's open_channel message
6368
6393
// Make sure A's dust limit is as we expect.
6369
6394
let open_channel_msg = node_a_chan. get_open_channel ( genesis_block ( network) . header . block_hash ( ) ) ;
6370
6395
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 ( ) ;
6372
6397
6373
6398
// Node B --> Node A: accept channel, explicitly setting B's dust limit.
6374
6399
let mut accept_channel_msg = node_b_chan. accept_inbound_channel ( ) ;
@@ -6432,7 +6457,7 @@ mod tests {
6432
6457
6433
6458
let node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6434
6459
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 ( ) ;
6436
6461
6437
6462
let commitment_tx_fee_0_htlcs = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( chan. feerate_per_kw , 0 , chan. opt_anchors ( ) ) ;
6438
6463
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 {
6481
6506
// Create Node A's channel pointing to Node B's pubkey
6482
6507
let node_b_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6483
6508
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 ( ) ;
6485
6510
6486
6511
// Create Node B's channel by receiving Node A's open_channel message
6487
6512
let open_channel_msg = node_a_chan. get_open_channel ( chain_hash) ;
6488
6513
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 ( ) ;
6490
6515
6491
6516
// Node B --> Node A: accept channel
6492
6517
let accept_channel_msg = node_b_chan. accept_inbound_channel ( ) ;
@@ -6543,7 +6568,7 @@ mod tests {
6543
6568
// Create a channel.
6544
6569
let node_b_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6545
6570
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 ( ) ;
6547
6572
assert ! ( node_a_chan. counterparty_forwarding_info. is_none( ) ) ;
6548
6573
assert_eq ! ( node_a_chan. holder_htlc_minimum_msat, 1 ) ; // the default
6549
6574
assert ! ( node_a_chan. counterparty_forwarding_info( ) . is_none( ) ) ;
@@ -6608,7 +6633,7 @@ mod tests {
6608
6633
let counterparty_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6609
6634
let mut config = UserConfig :: default ( ) ;
6610
6635
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
6612
6637
chan. holder_dust_limit_satoshis = 546 ;
6613
6638
chan. counterparty_selected_channel_reserve_satoshis = Some ( 0 ) ; // Filled in in accept_channel
6614
6639
0 commit comments