From be8223918137d5495ee7ad3ce8bf21d999f9915f Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Wed, 13 Oct 2021 21:14:35 +0000 Subject: [PATCH] Return the temporary channel id in success from `create_channel` This makes it more practical for users to track channels prior to funding, especially if the channel fails because the peer rejects it for a parameter mismatch. --- lightning/src/ln/channelmanager.rs | 37 ++++++++++++++--------- lightning/src/ln/functional_test_utils.rs | 3 +- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 298f88ce..ff129f67 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -1267,22 +1267,30 @@ impl ChannelMana /// Creates a new outbound channel to the given remote node and with the given value. /// - /// user_id will be provided back as user_channel_id in FundingGenerationReady events to allow - /// tracking of which events correspond with which create_channel call. Note that the - /// user_channel_id defaults to 0 for inbound channels, so you may wish to avoid using 0 for - /// user_id here. user_id has no meaning inside of LDK, it is simply copied to events and - /// otherwise ignored. + /// `user_id` will be provided back as `user_channel_id` in [`Event::FundingGenerationReady`] + /// to allow tracking of which events correspond with which `create_channel` call. Note that + /// the `user_channel_id` defaults to 0 for inbound channels, so you may wish to avoid using 0 + /// for `user_id` here. `user_id` has no meaning inside of LDK, it is simply copied to events + /// and otherwise ignored. /// - /// If successful, will generate a SendOpenChannel message event, so you should probably poll - /// PeerManager::process_events afterwards. - /// - /// Raises APIError::APIMisuseError when channel_value_satoshis > 2**24 or push_msat is - /// greater than channel_value_satoshis * 1k or channel_value_satoshis is < 1000. + /// Raises [`APIError::APIMisuseError`] when `channel_value_satoshis` > 2**24 or `push_msat` is + /// greater than `channel_value_satoshis * 1k` or `channel_value_satoshis < 1000`. /// /// Note that we do not check if you are currently connected to the given peer. If no /// connection is available, the outbound `open_channel` message may fail to send, resulting in - /// the channel eventually being silently forgotten. - pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, override_config: Option) -> Result<(), APIError> { + /// the channel eventually being silently forgotten (dropped on reload). + /// + /// Returns the new Channel's temporary `channel_id`. This ID will appear as + /// [`Event::FundingGenerationReady::temporary_channel_id`] and in + /// [`ChannelDetails::channel_id`] until after + /// [`ChannelManager::funding_transaction_generated`] is called, swapping the Channel's ID for + /// one derived from the funding transaction's TXID. If the counterparty rejects the channel + /// immediately, this temporary ID will appear in [`Event::ChannelClosed::channel_id`]. + /// + /// [`Event::FundingGenerationReady`]: events::Event::FundingGenerationReady + /// [`Event::FundingGenerationReady::temporary_channel_id`]: events::Event::FundingGenerationReady::temporary_channel_id + /// [`Event::ChannelClosed::channel_id`]: events::Event::ChannelClosed::channel_id + pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, push_msat: u64, user_id: u64, override_config: Option) -> Result<[u8; 32], APIError> { if channel_value_satoshis < 1000 { return Err(APIError::APIMisuseError { err: format!("Channel value must be at least 1000 satoshis. It was {}", channel_value_satoshis) }); } @@ -1305,8 +1313,9 @@ impl ChannelMana // We want to make sure the lock is actually acquired by PersistenceNotifierGuard. debug_assert!(&self.total_consistency_lock.try_write().is_err()); + let temporary_channel_id = channel.channel_id(); let mut channel_state = self.channel_state.lock().unwrap(); - match channel_state.by_id.entry(channel.channel_id()) { + match channel_state.by_id.entry(temporary_channel_id) { hash_map::Entry::Occupied(_) => { if cfg!(feature = "fuzztarget") { return Err(APIError::APIMisuseError { err: "Fuzzy bad RNG".to_owned() }); @@ -1320,7 +1329,7 @@ impl ChannelMana node_id: their_network_key, msg: res, }); - Ok(()) + Ok(temporary_channel_id) } fn list_channels_with_filter)) -> bool>(&self, f: Fn) -> Vec { diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 0d01961c..19969d0c 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -512,11 +512,12 @@ pub fn create_funding_transaction<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, expected_ } pub fn create_chan_between_nodes_with_value_init<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, channel_value: u64, push_msat: u64, a_flags: InitFeatures, b_flags: InitFeatures) -> Transaction { - node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None).unwrap(); + let create_chan_id = node_a.node.create_channel(node_b.node.get_our_node_id(), channel_value, push_msat, 42, None).unwrap(); node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), a_flags, &get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id())); node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), b_flags, &get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id())); let (temporary_channel_id, tx, funding_output) = create_funding_transaction(node_a, channel_value, 42); + assert_eq!(temporary_channel_id, create_chan_id); node_a.node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); check_added_monitors!(node_a, 0); -- 2.30.2