X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fchannelmanager.rs;h=f89aef6163c5d526f25fd52a446a87de34963a14;hb=14e52cd7a6382fdd71ce090a81eac9da3b9318de;hp=2ce466c9ac6d4efe7c0cea8a2af324a7d4ecaf19;hpb=b5a63070f52dbd2a9cadaf638de3f0b3d702bee7;p=rust-lightning diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 2ce466c9..f89aef61 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -1769,17 +1769,18 @@ impl ChannelMana }); } - fn close_channel_internal(&self, channel_id: &[u8; 32], target_feerate_sats_per_1000_weight: Option) -> Result<(), APIError> { + fn close_channel_internal(&self, channel_id: &[u8; 32], counterparty_node_id: &PublicKey, target_feerate_sats_per_1000_weight: Option) -> Result<(), APIError> { let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier); - let counterparty_node_id; let mut failed_htlcs: Vec<(HTLCSource, PaymentHash)>; let result: Result<(), _> = loop { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; match channel_state.by_id.entry(channel_id.clone()) { hash_map::Entry::Occupied(mut chan_entry) => { - counterparty_node_id = chan_entry.get().get_counterparty_node_id(); + if *counterparty_node_id != chan_entry.get().get_counterparty_node_id(){ + return Err(APIError::APIMisuseError { err: "The passed counterparty_node_id doesn't match the channel's counterparty node_id".to_owned() }); + } let per_peer_state = self.per_peer_state.read().unwrap(); let (shutdown_msg, monitor_update, htlcs) = match per_peer_state.get(&counterparty_node_id) { Some(peer_state) => { @@ -1804,7 +1805,7 @@ impl ChannelMana } channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown { - node_id: counterparty_node_id, + node_id: *counterparty_node_id, msg: shutdown_msg }); @@ -1827,7 +1828,7 @@ impl ChannelMana self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source.0, &htlc_source.1, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }); } - let _ = handle_error!(self, result, counterparty_node_id); + let _ = handle_error!(self, result, *counterparty_node_id); Ok(()) } @@ -1848,8 +1849,8 @@ impl ChannelMana /// [`ChannelConfig::force_close_avoidance_max_fee_satoshis`]: crate::util::config::ChannelConfig::force_close_avoidance_max_fee_satoshis /// [`Background`]: crate::chain::chaininterface::ConfirmationTarget::Background /// [`Normal`]: crate::chain::chaininterface::ConfirmationTarget::Normal - pub fn close_channel(&self, channel_id: &[u8; 32]) -> Result<(), APIError> { - self.close_channel_internal(channel_id, None) + pub fn close_channel(&self, channel_id: &[u8; 32], counterparty_node_id: &PublicKey) -> Result<(), APIError> { + self.close_channel_internal(channel_id, counterparty_node_id, None) } /// Begins the process of closing a channel. After this call (plus some timeout), no new HTLCs @@ -1871,8 +1872,8 @@ impl ChannelMana /// [`ChannelConfig::force_close_avoidance_max_fee_satoshis`]: crate::util::config::ChannelConfig::force_close_avoidance_max_fee_satoshis /// [`Background`]: crate::chain::chaininterface::ConfirmationTarget::Background /// [`Normal`]: crate::chain::chaininterface::ConfirmationTarget::Normal - pub fn close_channel_with_target_feerate(&self, channel_id: &[u8; 32], target_feerate_sats_per_1000_weight: u32) -> Result<(), APIError> { - self.close_channel_internal(channel_id, Some(target_feerate_sats_per_1000_weight)) + pub fn close_channel_with_target_feerate(&self, channel_id: &[u8; 32], counterparty_node_id: &PublicKey, target_feerate_sats_per_1000_weight: u32) -> Result<(), APIError> { + self.close_channel_internal(channel_id, counterparty_node_id, Some(target_feerate_sats_per_1000_weight)) } #[inline] @@ -1891,22 +1892,18 @@ impl ChannelMana } } - /// `peer_node_id` should be set when we receive a message from a peer, but not set when the + /// `peer_msg` should be set when we receive a message from a peer, but not set when the /// user closes, which will be re-exposed as the `ChannelClosed` reason. - fn force_close_channel_with_peer(&self, channel_id: &[u8; 32], peer_node_id: Option<&PublicKey>, peer_msg: Option<&String>) -> Result { + fn force_close_channel_with_peer(&self, channel_id: &[u8; 32], peer_node_id: &PublicKey, peer_msg: Option<&String>) -> Result { let mut chan = { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; if let hash_map::Entry::Occupied(chan) = channel_state.by_id.entry(channel_id.clone()) { - if let Some(node_id) = peer_node_id { - if chan.get().get_counterparty_node_id() != *node_id { - return Err(APIError::ChannelUnavailable{err: "No such channel".to_owned()}); - } + if chan.get().get_counterparty_node_id() != *peer_node_id { + return Err(APIError::ChannelUnavailable{err: "No such channel".to_owned()}); } - if peer_node_id.is_some() { - if let Some(peer_msg) = peer_msg { - self.issue_channel_close_events(chan.get(),ClosureReason::CounterpartyForceClosed { peer_msg: peer_msg.to_string() }); - } + if let Some(peer_msg) = peer_msg { + self.issue_channel_close_events(chan.get(),ClosureReason::CounterpartyForceClosed { peer_msg: peer_msg.to_string() }); } else { self.issue_channel_close_events(chan.get(),ClosureReason::HolderForceClosed); } @@ -1928,10 +1925,12 @@ impl ChannelMana } /// Force closes a channel, immediately broadcasting the latest local commitment transaction to - /// the chain and rejecting new HTLCs on the given channel. Fails if channel_id is unknown to the manager. - pub fn force_close_channel(&self, channel_id: &[u8; 32]) -> Result<(), APIError> { + /// the chain and rejecting new HTLCs on the given channel. Fails if `channel_id` is unknown to + /// the manager, or if the `counterparty_node_id` isn't the counterparty of the corresponding + /// channel. + pub fn force_close_channel(&self, channel_id: &[u8; 32], counterparty_node_id: &PublicKey) -> Result<(), APIError> { let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier); - match self.force_close_channel_with_peer(channel_id, None, None) { + match self.force_close_channel_with_peer(channel_id, counterparty_node_id, None) { Ok(counterparty_node_id) => { self.channel_state.lock().unwrap().pending_msg_events.push( events::MessageSendEvent::HandleError { @@ -1951,7 +1950,7 @@ impl ChannelMana /// for each to the chain and rejecting new HTLCs on each. pub fn force_close_all_channels(&self) { for chan in self.list_channels() { - let _ = self.force_close_channel(&chan.channel_id); + let _ = self.force_close_channel(&chan.channel_id, &chan.counterparty.node_id); } } @@ -4212,6 +4211,7 @@ impl ChannelMana let mut pending_events = self.pending_events.lock().unwrap(); pending_events.push(events::Event::FundingGenerationReady { temporary_channel_id: msg.temporary_channel_id, + counterparty_node_id: *counterparty_node_id, channel_value_satoshis: value, output_script, user_channel_id: user_id, @@ -5814,7 +5814,7 @@ impl for chan in self.list_channels() { if chan.counterparty.node_id == *counterparty_node_id { // Untrusted messages from peer, we throw away the error if id points to a non-existent channel - let _ = self.force_close_channel_with_peer(&chan.channel_id, Some(counterparty_node_id), Some(&msg.data)); + let _ = self.force_close_channel_with_peer(&chan.channel_id, counterparty_node_id, Some(&msg.data)); } } } else { @@ -5836,7 +5836,7 @@ impl } // Untrusted messages from peer, we throw away the error if id points to a non-existent channel - let _ = self.force_close_channel_with_peer(&msg.channel_id, Some(counterparty_node_id), Some(&msg.data)); + let _ = self.force_close_channel_with_peer(&msg.channel_id, counterparty_node_id, Some(&msg.data)); } } }