Skip to content

Commit 8d8ee55

Browse files
authored
Merge pull request #1790 from tnull/2022-10-inbound-user-channel-id-randomization
Randomize `user_channel_id` for inbound channels
2 parents 838d486 + dc3ff54 commit 8d8ee55

File tree

7 files changed

+192
-74
lines changed

7 files changed

+192
-74
lines changed

fuzz/src/full_stack.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
403403
// Adding new calls to `KeysInterface::get_secure_random_bytes` during startup can change all the
404404
// keys subsequently generated in this test. Rather than regenerating all the messages manually,
405405
// it's easier to just increment the counter here so the keys don't change.
406-
keys_manager.counter.fetch_sub(2, Ordering::AcqRel);
406+
keys_manager.counter.fetch_sub(3, Ordering::AcqRel);
407407
let our_id = PublicKey::from_secret_key(&Secp256k1::signing_only(), &keys_manager.get_node_secret(Recipient::Node).unwrap());
408408
let network_graph = Arc::new(NetworkGraph::new(genesis_block(network).block_hash(), Arc::clone(&logger)));
409409
let gossip_sync = Arc::new(P2PGossipSync::new(Arc::clone(&network_graph), None, Arc::clone(&logger)));

lightning/src/ln/channel.rs

+28-7
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ pub(super) struct Channel<Signer: Sign> {
509509

510510
inbound_handshake_limits_override: Option<ChannelHandshakeLimits>,
511511

512-
user_id: u64,
512+
user_id: u128,
513513

514514
channel_id: [u8; 32],
515515
channel_state: u32,
@@ -902,7 +902,7 @@ impl<Signer: Sign> Channel<Signer> {
902902
// Constructors:
903903
pub fn new_outbound<K: Deref, F: Deref>(
904904
fee_estimator: &LowerBoundedFeeEstimator<F>, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
905-
channel_value_satoshis: u64, push_msat: u64, user_id: u64, config: &UserConfig, current_chain_height: u32,
905+
channel_value_satoshis: u64, push_msat: u64, user_id: u128, config: &UserConfig, current_chain_height: u32,
906906
outbound_scid_alias: u64
907907
) -> Result<Channel<Signer>, APIError>
908908
where K::Target: KeysInterface<Signer = Signer>,
@@ -1102,7 +1102,7 @@ impl<Signer: Sign> Channel<Signer> {
11021102
/// Assumes chain_hash has already been checked and corresponds with what we expect!
11031103
pub fn new_from_req<K: Deref, F: Deref, L: Deref>(
11041104
fee_estimator: &LowerBoundedFeeEstimator<F>, keys_provider: &K, counterparty_node_id: PublicKey, their_features: &InitFeatures,
1105-
msg: &msgs::OpenChannel, user_id: u64, config: &UserConfig, current_chain_height: u32, logger: &L,
1105+
msg: &msgs::OpenChannel, user_id: u128, config: &UserConfig, current_chain_height: u32, logger: &L,
11061106
outbound_scid_alias: u64
11071107
) -> Result<Channel<Signer>, ChannelError>
11081108
where K::Target: KeysInterface<Signer = Signer>,
@@ -4482,7 +4482,7 @@ impl<Signer: Sign> Channel<Signer> {
44824482

44834483
/// Gets the "user_id" value passed into the construction of this channel. It has no special
44844484
/// meaning and exists only to allow users to have a persistent identifier of a channel.
4485-
pub fn get_user_id(&self) -> u64 {
4485+
pub fn get_user_id(&self) -> u128 {
44864486
self.user_id
44874487
}
44884488

@@ -5178,7 +5178,7 @@ impl<Signer: Sign> Channel<Signer> {
51785178
/// should be sent back to the counterparty node.
51795179
///
51805180
/// [`msgs::AcceptChannel`]: crate::ln::msgs::AcceptChannel
5181-
pub fn accept_inbound_channel(&mut self, user_id: u64) -> msgs::AcceptChannel {
5181+
pub fn accept_inbound_channel(&mut self, user_id: u128) -> msgs::AcceptChannel {
51825182
if self.is_outbound() {
51835183
panic!("Tried to send accept_channel for an outbound channel?");
51845184
}
@@ -6007,7 +6007,11 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
60076007

60086008
write_ver_prefix!(writer, SERIALIZATION_VERSION, MIN_SERIALIZATION_VERSION);
60096009

6010-
self.user_id.write(writer)?;
6010+
// `user_id` used to be a single u64 value. In order to remain backwards compatible with
6011+
// versions prior to 0.0.113, the u128 is serialized as two separate u64 values. We write
6012+
// the low bytes now and the optional high bytes later.
6013+
let user_id_low = self.user_id as u64;
6014+
user_id_low.write(writer)?;
60116015

60126016
// Version 1 deserializers expected to read parts of the config object here. Version 2
60136017
// deserializers (0.0.99) now read config through TLVs, and as we now require them for
@@ -6254,6 +6258,11 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
62546258

62556259
let channel_ready_event_emitted = Some(self.channel_ready_event_emitted);
62566260

6261+
// `user_id` used to be a single u64 value. In order to remain backwards compatible with
6262+
// versions prior to 0.0.113, the u128 is serialized as two separate u64 values. Therefore,
6263+
// we write the high bytes as an option here.
6264+
let user_id_high_opt = Some((self.user_id >> 64) as u64);
6265+
62576266
write_tlv_fields!(writer, {
62586267
(0, self.announcement_sigs, option),
62596268
// minimum_depth and counterparty_selected_channel_reserve_satoshis used to have a
@@ -6277,6 +6286,7 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
62776286
(19, self.latest_inbound_scid_alias, option),
62786287
(21, self.outbound_scid_alias, required),
62796288
(23, channel_ready_event_emitted, option),
6289+
(25, user_id_high_opt, option),
62806290
});
62816291

62826292
Ok(())
@@ -6290,7 +6300,10 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as KeysInte
62906300
let (keys_source, serialized_height) = args;
62916301
let ver = read_ver_prefix!(reader, SERIALIZATION_VERSION);
62926302

6293-
let user_id = Readable::read(reader)?;
6303+
// `user_id` used to be a single u64 value. In order to remain backwards compatible with
6304+
// versions prior to 0.0.113, the u128 is serialized as two separate u64 values. We read
6305+
// the low bytes now and the high bytes later.
6306+
let user_id_low: u64 = Readable::read(reader)?;
62946307

62956308
let mut config = Some(LegacyChannelConfig::default());
62966309
if ver == 1 {
@@ -6536,6 +6549,8 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as KeysInte
65366549
let mut outbound_scid_alias = None;
65376550
let mut channel_ready_event_emitted = None;
65386551

6552+
let mut user_id_high_opt: Option<u64> = None;
6553+
65396554
read_tlv_fields!(reader, {
65406555
(0, announcement_sigs, option),
65416556
(1, minimum_depth, option),
@@ -6553,6 +6568,7 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as KeysInte
65536568
(19, latest_inbound_scid_alias, option),
65546569
(21, outbound_scid_alias, option),
65556570
(23, channel_ready_event_emitted, option),
6571+
(25, user_id_high_opt, option),
65566572
});
65576573

65586574
if let Some(preimages) = preimages_opt {
@@ -6589,6 +6605,11 @@ impl<'a, K: Deref> ReadableArgs<(&'a K, u32)> for Channel<<K::Target as KeysInte
65896605
let mut secp_ctx = Secp256k1::new();
65906606
secp_ctx.seeded_randomize(&keys_source.get_secure_random_bytes());
65916607

6608+
// `user_id` used to be a single u64 value. In order to remain backwards
6609+
// compatible with versions prior to 0.0.113, the u128 is serialized as two
6610+
// separate u64 values.
6611+
let user_id = user_id_low as u128 + ((user_id_high_opt.unwrap_or(0) as u128) << 64);
6612+
65926613
Ok(Channel {
65936614
user_id,
65946615

lightning/src/ln/channelmanager.rs

+119-40
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ type ShutdownResult = (Option<(OutPoint, ChannelMonitorUpdate)>, Vec<(HTLCSource
292292
293293
struct MsgHandleErrInternal {
294294
err: msgs::LightningError,
295-
chan_id: Option<([u8; 32], u64)>, // If Some a channel of ours has been closed
295+
chan_id: Option<([u8; 32], u128)>, // If Some a channel of ours has been closed
296296
shutdown_finish: Option<(ShutdownResult, Option<msgs::ChannelUpdate>)>,
297297
}
298298
impl MsgHandleErrInternal {
@@ -328,7 +328,7 @@ impl MsgHandleErrInternal {
328328
Self { err, chan_id: None, shutdown_finish: None }
329329
}
330330
#[inline]
331-
fn from_finish_shutdown(err: String, channel_id: [u8; 32], user_channel_id: u64, shutdown_res: ShutdownResult, channel_update: Option<msgs::ChannelUpdate>) -> Self {
331+
fn from_finish_shutdown(err: String, channel_id: [u8; 32], user_channel_id: u128, shutdown_res: ShutdownResult, channel_update: Option<msgs::ChannelUpdate>) -> Self {
332332
Self {
333333
err: LightningError {
334334
err: err.clone(),
@@ -1086,8 +1086,9 @@ pub struct ChannelDetails {
10861086
///
10871087
/// [`outbound_capacity_msat`]: ChannelDetails::outbound_capacity_msat
10881088
pub unspendable_punishment_reserve: Option<u64>,
1089-
/// The `user_channel_id` passed in to create_channel, or 0 if the channel was inbound.
1090-
pub user_channel_id: u64,
1089+
/// The `user_channel_id` passed in to create_channel, or a random value if the channel was
1090+
/// inbound.
1091+
pub user_channel_id: u128,
10911092
/// Our total balance. This is the amount we would get if we close the channel.
10921093
/// This value is not exact. Due to various in-flight changes and feerate changes, exactly this
10931094
/// amount is not likely to be recoverable on close.
@@ -1722,10 +1723,9 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
17221723
///
17231724
/// `user_channel_id` will be provided back as in
17241725
/// [`Event::FundingGenerationReady::user_channel_id`] to allow tracking of which events
1725-
/// correspond with which `create_channel` call. Note that the `user_channel_id` defaults to 0
1726-
/// for inbound channels, so you may wish to avoid using 0 for `user_channel_id` here.
1727-
/// `user_channel_id` has no meaning inside of LDK, it is simply copied to events and otherwise
1728-
/// ignored.
1726+
/// correspond with which `create_channel` call. Note that the `user_channel_id` defaults to a
1727+
/// randomized value for inbound channels. `user_channel_id` has no meaning inside of LDK, it
1728+
/// is simply copied to events and otherwise ignored.
17291729
///
17301730
/// Raises [`APIError::APIMisuseError`] when `channel_value_satoshis` > 2**24 or `push_msat` is
17311731
/// greater than `channel_value_satoshis * 1k` or `channel_value_satoshis < 1000`.
@@ -1744,7 +1744,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
17441744
/// [`Event::FundingGenerationReady::user_channel_id`]: events::Event::FundingGenerationReady::user_channel_id
17451745
/// [`Event::FundingGenerationReady::temporary_channel_id`]: events::Event::FundingGenerationReady::temporary_channel_id
17461746
/// [`Event::ChannelClosed::channel_id`]: events::Event::ChannelClosed::channel_id
1747-
pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_channel_id: u64, override_config: Option<UserConfig>) -> Result<[u8; 32], APIError> {
1747+
pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_channel_id: u128, override_config: Option<UserConfig>) -> Result<[u8; 32], APIError> {
17481748
if channel_value_satoshis < 1000 {
17491749
return Err(APIError::APIMisuseError { err: format!("Channel value must be at least 1000 satoshis. It was {}", channel_value_satoshis) });
17501750
}
@@ -4536,7 +4536,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
45364536
///
45374537
/// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
45384538
/// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
4539-
pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u64) -> Result<(), APIError> {
4539+
pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u128) -> Result<(), APIError> {
45404540
self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, false, user_channel_id)
45414541
}
45424542

@@ -4558,11 +4558,11 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
45584558
///
45594559
/// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest
45604560
/// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id
4561-
pub fn accept_inbound_channel_from_trusted_peer_0conf(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u64) -> Result<(), APIError> {
4561+
pub fn accept_inbound_channel_from_trusted_peer_0conf(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u128) -> Result<(), APIError> {
45624562
self.do_accept_inbound_channel(temporary_channel_id, counterparty_node_id, true, user_channel_id)
45634563
}
45644564

4565-
fn do_accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, accept_0conf: bool, user_channel_id: u64) -> Result<(), APIError> {
4565+
fn do_accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, accept_0conf: bool, user_channel_id: u128) -> Result<(), APIError> {
45664566
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
45674567

45684568
let mut channel_state_lock = self.channel_state.lock().unwrap();
@@ -4610,9 +4610,13 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
46104610
return Err(MsgHandleErrInternal::send_err_msg_no_close("No inbound channels accepted".to_owned(), msg.temporary_channel_id.clone()));
46114611
}
46124612

4613+
let mut random_bytes = [0u8; 16];
4614+
random_bytes.copy_from_slice(&self.keys_manager.get_secure_random_bytes()[..16]);
4615+
let user_channel_id = u128::from_be_bytes(random_bytes);
4616+
46134617
let outbound_scid_alias = self.create_and_insert_outbound_scid_alias();
46144618
let mut channel = match Channel::new_from_req(&self.fee_estimator, &self.keys_manager,
4615-
counterparty_node_id.clone(), &their_features, msg, 0, &self.default_configuration,
4619+
counterparty_node_id.clone(), &their_features, msg, user_channel_id, &self.default_configuration,
46164620
self.best_block.read().unwrap().height(), &self.logger, outbound_scid_alias)
46174621
{
46184622
Err(e) => {
@@ -6450,33 +6454,108 @@ impl_writeable_tlv_based!(ChannelCounterparty, {
64506454
(11, outbound_htlc_maximum_msat, option),
64516455
});
64526456

6453-
impl_writeable_tlv_based!(ChannelDetails, {
6454-
(1, inbound_scid_alias, option),
6455-
(2, channel_id, required),
6456-
(3, channel_type, option),
6457-
(4, counterparty, required),
6458-
(5, outbound_scid_alias, option),
6459-
(6, funding_txo, option),
6460-
(7, config, option),
6461-
(8, short_channel_id, option),
6462-
(10, channel_value_satoshis, required),
6463-
(12, unspendable_punishment_reserve, option),
6464-
(14, user_channel_id, required),
6465-
(16, balance_msat, required),
6466-
(18, outbound_capacity_msat, required),
6467-
// Note that by the time we get past the required read above, outbound_capacity_msat will be
6468-
// filled in, so we can safely unwrap it here.
6469-
(19, next_outbound_htlc_limit_msat, (default_value, outbound_capacity_msat.0.unwrap() as u64)),
6470-
(20, inbound_capacity_msat, required),
6471-
(22, confirmations_required, option),
6472-
(24, force_close_spend_delay, option),
6473-
(26, is_outbound, required),
6474-
(28, is_channel_ready, required),
6475-
(30, is_usable, required),
6476-
(32, is_public, required),
6477-
(33, inbound_htlc_minimum_msat, option),
6478-
(35, inbound_htlc_maximum_msat, option),
6479-
});
6457+
impl Writeable for ChannelDetails {
6458+
fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
6459+
// `user_channel_id` used to be a single u64 value. In order to remain backwards compatible with
6460+
// versions prior to 0.0.113, the u128 is serialized as two separate u64 values.
6461+
let user_channel_id_low = self.user_channel_id as u64;
6462+
let user_channel_id_high_opt = Some((self.user_channel_id >> 64) as u64);
6463+
write_tlv_fields!(writer, {
6464+
(1, self.inbound_scid_alias, option),
6465+
(2, self.channel_id, required),
6466+
(3, self.channel_type, option),
6467+
(4, self.counterparty, required),
6468+
(5, self.outbound_scid_alias, option),
6469+
(6, self.funding_txo, option),
6470+
(7, self.config, option),
6471+
(8, self.short_channel_id, option),
6472+
(10, self.channel_value_satoshis, required),
6473+
(12, self.unspendable_punishment_reserve, option),
6474+
(14, user_channel_id_low, required),
6475+
(16, self.balance_msat, required),
6476+
(18, self.outbound_capacity_msat, required),
6477+
// Note that by the time we get past the required read above, outbound_capacity_msat will be
6478+
// filled in, so we can safely unwrap it here.
6479+
(19, self.next_outbound_htlc_limit_msat, (default_value, outbound_capacity_msat.0.unwrap() as u64)),
6480+
(20, self.inbound_capacity_msat, required),
6481+
(22, self.confirmations_required, option),
6482+
(24, self.force_close_spend_delay, option),
6483+
(26, self.is_outbound, required),
6484+
(28, self.is_channel_ready, required),
6485+
(30, self.is_usable, required),
6486+
(32, self.is_public, required),
6487+
(33, self.inbound_htlc_minimum_msat, option),
6488+
(35, self.inbound_htlc_maximum_msat, option),
6489+
(37, user_channel_id_high_opt, option),
6490+
});
6491+
Ok(())
6492+
}
6493+
}
6494+
6495+
impl Readable for ChannelDetails {
6496+
fn read<R: Read>(reader: &mut R) -> Result<Self, DecodeError> {
6497+
init_and_read_tlv_fields!(reader, {
6498+
(1, inbound_scid_alias, option),
6499+
(2, channel_id, required),
6500+
(3, channel_type, option),
6501+
(4, counterparty, required),
6502+
(5, outbound_scid_alias, option),
6503+
(6, funding_txo, option),
6504+
(7, config, option),
6505+
(8, short_channel_id, option),
6506+
(10, channel_value_satoshis, required),
6507+
(12, unspendable_punishment_reserve, option),
6508+
(14, user_channel_id_low, required),
6509+
(16, balance_msat, required),
6510+
(18, outbound_capacity_msat, required),
6511+
// Note that by the time we get past the required read above, outbound_capacity_msat will be
6512+
// filled in, so we can safely unwrap it here.
6513+
(19, next_outbound_htlc_limit_msat, (default_value, outbound_capacity_msat.0.unwrap() as u64)),
6514+
(20, inbound_capacity_msat, required),
6515+
(22, confirmations_required, option),
6516+
(24, force_close_spend_delay, option),
6517+
(26, is_outbound, required),
6518+
(28, is_channel_ready, required),
6519+
(30, is_usable, required),
6520+
(32, is_public, required),
6521+
(33, inbound_htlc_minimum_msat, option),
6522+
(35, inbound_htlc_maximum_msat, option),
6523+
(37, user_channel_id_high_opt, option),
6524+
});
6525+
6526+
// `user_channel_id` used to be a single u64 value. In order to remain backwards compatible with
6527+
// versions prior to 0.0.113, the u128 is serialized as two separate u64 values.
6528+
let user_channel_id_low: u64 = user_channel_id_low.0.unwrap();
6529+
let user_channel_id = user_channel_id_low as u128 +
6530+
((user_channel_id_high_opt.unwrap_or(0 as u64) as u128) << 64);
6531+
6532+
Ok(Self {
6533+
inbound_scid_alias,
6534+
channel_id: channel_id.0.unwrap(),
6535+
channel_type,
6536+
counterparty: counterparty.0.unwrap(),
6537+
outbound_scid_alias,
6538+
funding_txo,
6539+
config,
6540+
short_channel_id,
6541+
channel_value_satoshis: channel_value_satoshis.0.unwrap(),
6542+
unspendable_punishment_reserve,
6543+
user_channel_id,
6544+
balance_msat: balance_msat.0.unwrap(),
6545+
outbound_capacity_msat: outbound_capacity_msat.0.unwrap(),
6546+
next_outbound_htlc_limit_msat: next_outbound_htlc_limit_msat.0.unwrap(),
6547+
inbound_capacity_msat: inbound_capacity_msat.0.unwrap(),
6548+
confirmations_required,
6549+
force_close_spend_delay,
6550+
is_outbound: is_outbound.0.unwrap(),
6551+
is_channel_ready: is_channel_ready.0.unwrap(),
6552+
is_usable: is_usable.0.unwrap(),
6553+
is_public: is_public.0.unwrap(),
6554+
inbound_htlc_minimum_msat,
6555+
inbound_htlc_maximum_msat,
6556+
})
6557+
}
6558+
}
64806559

64816560
impl_writeable_tlv_based!(PhantomRouteHints, {
64826561
(2, channels, vec_type),

lightning/src/ln/functional_test_utils.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -618,7 +618,7 @@ macro_rules! check_added_monitors {
618618
}
619619
}
620620

621-
pub fn create_funding_transaction<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, expected_counterparty_node_id: &PublicKey, expected_chan_value: u64, expected_user_chan_id: u64) -> ([u8; 32], Transaction, OutPoint) {
621+
pub fn create_funding_transaction<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, expected_counterparty_node_id: &PublicKey, expected_chan_value: u64, expected_user_chan_id: u128) -> ([u8; 32], Transaction, OutPoint) {
622622
let chan_id = *node.network_chan_count.borrow();
623623

624624
let events = node.node.get_and_clear_pending_events();

0 commit comments

Comments
 (0)