@@ -702,6 +702,12 @@ 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
+
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 ,
705
711
}
706
712
707
713
#[ cfg( any( test, fuzzing) ) ]
@@ -807,7 +813,8 @@ impl<Signer: Sign> Channel<Signer> {
807
813
// Constructors:
808
814
pub fn new_outbound < K : Deref , F : Deref > (
809
815
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
811
818
) -> Result < Channel < Signer > , APIError >
812
819
where K :: Target : KeysInterface < Signer = Signer > ,
813
820
F :: Target : FeeEstimator ,
@@ -955,6 +962,7 @@ impl<Signer: Sign> Channel<Signer> {
955
962
workaround_lnd_bug_4006 : None ,
956
963
957
964
latest_inbound_scid_alias : None ,
965
+ outbound_scid_alias,
958
966
959
967
#[ cfg( any( test, fuzzing) ) ]
960
968
historical_inbound_htlc_fulfills : HashSet :: new ( ) ,
@@ -993,7 +1001,8 @@ impl<Signer: Sign> Channel<Signer> {
993
1001
/// Assumes chain_hash has already been checked and corresponds with what we expect!
994
1002
pub fn new_from_req < K : Deref , F : Deref , L : Deref > (
995
1003
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
997
1006
) -> Result < Channel < Signer > , ChannelError >
998
1007
where K :: Target : KeysInterface < Signer = Signer > ,
999
1008
F :: Target : FeeEstimator ,
@@ -1262,6 +1271,7 @@ impl<Signer: Sign> Channel<Signer> {
1262
1271
workaround_lnd_bug_4006 : None ,
1263
1272
1264
1273
latest_inbound_scid_alias : None ,
1274
+ outbound_scid_alias,
1265
1275
1266
1276
#[ cfg( any( test, fuzzing) ) ]
1267
1277
historical_inbound_htlc_fulfills : HashSet :: new ( ) ,
@@ -3477,7 +3487,7 @@ impl<Signer: Sign> Channel<Signer> {
3477
3487
Some ( msgs:: FundingLocked {
3478
3488
channel_id : self . channel_id ( ) ,
3479
3489
next_per_commitment_point,
3480
- short_channel_id_alias : None ,
3490
+ short_channel_id_alias : Some ( self . outbound_scid_alias ) ,
3481
3491
} )
3482
3492
} else { None } ;
3483
3493
@@ -3699,7 +3709,7 @@ impl<Signer: Sign> Channel<Signer> {
3699
3709
funding_locked : Some ( msgs:: FundingLocked {
3700
3710
channel_id : self . channel_id ( ) ,
3701
3711
next_per_commitment_point,
3702
- short_channel_id_alias : None ,
3712
+ short_channel_id_alias : Some ( self . outbound_scid_alias ) ,
3703
3713
} ) ,
3704
3714
raa : None , commitment_update : None , mon_update : None ,
3705
3715
order : RAACommitmentOrder :: CommitmentFirst ,
@@ -3735,7 +3745,7 @@ impl<Signer: Sign> Channel<Signer> {
3735
3745
Some ( msgs:: FundingLocked {
3736
3746
channel_id : self . channel_id ( ) ,
3737
3747
next_per_commitment_point,
3738
- short_channel_id_alias : None ,
3748
+ short_channel_id_alias : Some ( self . outbound_scid_alias ) ,
3739
3749
} )
3740
3750
} else { None } ;
3741
3751
@@ -4223,6 +4233,17 @@ impl<Signer: Sign> Channel<Signer> {
4223
4233
self . latest_inbound_scid_alias
4224
4234
}
4225
4235
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
+
4226
4247
/// Returns the funding_txo we either got from our peer, or were given by
4227
4248
/// get_outbound_funding_created.
4228
4249
pub fn get_funding_txo ( & self ) -> Option < OutPoint > {
@@ -4475,7 +4496,7 @@ impl<Signer: Sign> Channel<Signer> {
4475
4496
return Some ( msgs:: FundingLocked {
4476
4497
channel_id : self . channel_id ,
4477
4498
next_per_commitment_point,
4478
- short_channel_id_alias : None ,
4499
+ short_channel_id_alias : Some ( self . outbound_scid_alias ) ,
4479
4500
} ) ;
4480
4501
}
4481
4502
} else {
@@ -5795,6 +5816,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
5795
5816
( 15 , preimages, vec_type) ,
5796
5817
( 17 , self . announcement_sigs_state, required) ,
5797
5818
( 19 , self . latest_inbound_scid_alias, option) ,
5819
+ ( 21 , self . outbound_scid_alias, required) ,
5798
5820
} ) ;
5799
5821
5800
5822
Ok ( ( ) )
@@ -6051,6 +6073,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
6051
6073
// AnnouncementSignatures" which implies we'll re-send it on reconnect, but that's fine.
6052
6074
let mut announcement_sigs_state = Some ( AnnouncementSigsState :: NotSent ) ;
6053
6075
let mut latest_inbound_scid_alias = None ;
6076
+ let mut outbound_scid_alias = None ;
6054
6077
6055
6078
read_tlv_fields ! ( reader, {
6056
6079
( 0 , announcement_sigs, option) ,
@@ -6067,6 +6090,7 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
6067
6090
( 15 , preimages_opt, vec_type) ,
6068
6091
( 17 , announcement_sigs_state, option) ,
6069
6092
( 19 , latest_inbound_scid_alias, option) ,
6093
+ ( 21 , outbound_scid_alias, option) ,
6070
6094
} ) ;
6071
6095
6072
6096
if let Some ( preimages) = preimages_opt {
@@ -6202,6 +6226,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<Signer>
6202
6226
workaround_lnd_bug_4006 : None ,
6203
6227
6204
6228
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 ) ,
6205
6231
6206
6232
#[ cfg( any( test, fuzzing) ) ]
6207
6233
historical_inbound_htlc_fulfills,
@@ -6325,7 +6351,7 @@ mod tests {
6325
6351
let secp_ctx = Secp256k1 :: new ( ) ;
6326
6352
let node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6327
6353
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 ) {
6329
6355
Err ( APIError :: IncompatibleShutdownScript { script } ) => {
6330
6356
assert_eq ! ( script. into_inner( ) , non_v0_segwit_shutdown_script. into_inner( ) ) ;
6331
6357
} ,
@@ -6347,7 +6373,7 @@ mod tests {
6347
6373
6348
6374
let node_a_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6349
6375
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 ( ) ;
6351
6377
6352
6378
// Now change the fee so we can check that the fee in the open_channel message is the
6353
6379
// same as the old fee.
@@ -6373,13 +6399,13 @@ mod tests {
6373
6399
// Create Node A's channel pointing to Node B's pubkey
6374
6400
let node_b_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6375
6401
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 ( ) ;
6377
6403
6378
6404
// Create Node B's channel by receiving Node A's open_channel message
6379
6405
// Make sure A's dust limit is as we expect.
6380
6406
let open_channel_msg = node_a_chan. get_open_channel ( genesis_block ( network) . header . block_hash ( ) ) ;
6381
6407
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 ( ) ;
6383
6409
6384
6410
// Node B --> Node A: accept channel, explicitly setting B's dust limit.
6385
6411
let mut accept_channel_msg = node_b_chan. accept_inbound_channel ( ) ;
@@ -6443,7 +6469,7 @@ mod tests {
6443
6469
6444
6470
let node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6445
6471
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 ( ) ;
6447
6473
6448
6474
let commitment_tx_fee_0_htlcs = Channel :: < EnforcingSigner > :: commit_tx_fee_msat ( chan. feerate_per_kw , 0 , chan. opt_anchors ( ) ) ;
6449
6475
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 {
6492
6518
// Create Node A's channel pointing to Node B's pubkey
6493
6519
let node_b_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6494
6520
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 ( ) ;
6496
6522
6497
6523
// Create Node B's channel by receiving Node A's open_channel message
6498
6524
let open_channel_msg = node_a_chan. get_open_channel ( chain_hash) ;
6499
6525
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 ( ) ;
6501
6527
6502
6528
// Node B --> Node A: accept channel
6503
6529
let accept_channel_msg = node_b_chan. accept_inbound_channel ( ) ;
@@ -6554,7 +6580,7 @@ mod tests {
6554
6580
// Create a channel.
6555
6581
let node_b_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6556
6582
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 ( ) ;
6558
6584
assert ! ( node_a_chan. counterparty_forwarding_info. is_none( ) ) ;
6559
6585
assert_eq ! ( node_a_chan. holder_htlc_minimum_msat, 1 ) ; // the default
6560
6586
assert ! ( node_a_chan. counterparty_forwarding_info( ) . is_none( ) ) ;
@@ -6619,7 +6645,7 @@ mod tests {
6619
6645
let counterparty_node_id = PublicKey :: from_secret_key ( & secp_ctx, & SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ) ;
6620
6646
let mut config = UserConfig :: default ( ) ;
6621
6647
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
6623
6649
chan. holder_dust_limit_satoshis = 546 ;
6624
6650
chan. counterparty_selected_channel_reserve_satoshis = Some ( 0 ) ; // Filled in in accept_channel
6625
6651
0 commit comments