Clean up channel error handling a ton
[rust-lightning] / src / ln / channelmanager.rs
index 8be2348a7e1e5374ba82bc063a3c7ac25a668bb8..d2854ca741145eaeaefc11ab673cbe53c71d3f2c 100644 (file)
@@ -41,8 +41,8 @@ pub struct PendingForwardHTLCInfo {
        amt_to_forward: u64,
        outgoing_cltv_value: u32,
 }
-//TODO: This is public, and needed to call Channel::update_add_htlc, so there needs to be a way to
-//initialize it usefully...probably make it optional in Channel instead).
+
+#[cfg(feature = "fuzztarget")]
 impl PendingForwardHTLCInfo {
        pub fn dummy() -> Self {
                Self {
@@ -635,7 +635,7 @@ impl ChannelManager {
                        let mut channel_state_lock = self.channel_state.lock().unwrap();
                        let channel_state = channel_state_lock.borrow_parts();
 
-                       if Instant::now() < *channel_state.next_forward {
+                       if cfg!(not(feature = "fuzztarget")) && Instant::now() < *channel_state.next_forward {
                                return;
                        }
 
@@ -906,6 +906,7 @@ impl ChainListener for ChannelManager {
                                        },
                                        None => {}
                                }
+                               //TODO: Check if channel was closed (or disabled) here
                        }
                        for to_insert in short_to_ids_to_insert {
                                channel_state.short_to_id.insert(to_insert.0, to_insert.1);
@@ -1120,7 +1121,7 @@ impl ChannelMessageHandler for ChannelManager {
                        ($msg: expr, $err_code: expr, $data: expr) => {
                                return Err(msgs::HandleError {
                                        err: $msg,
-                                       msg: Some(msgs::ErrorMessage::UpdateFailHTLC {
+                                       msg: Some(msgs::ErrorAction::UpdateFailHTLC {
                                                msg: msgs::UpdateFailHTLC {
                                                        channel_id: msg.channel_id,
                                                        htlc_id: msg.htlc_id,
@@ -1480,6 +1481,37 @@ impl ChannelMessageHandler for ChannelManager {
                pending_events.push(events::Event::BroadcastChannelAnnouncement { msg: chan_announcement, update_msg: chan_update });
                Ok(())
        }
+
+       fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool) {
+               let mut channel_state_lock = self.channel_state.lock().unwrap();
+               let channel_state = channel_state_lock.borrow_parts();
+               let short_to_id = channel_state.short_to_id;
+               if no_connection_possible {
+                       channel_state.by_id.retain(move |_, chan| {
+                               if chan.get_their_node_id() == *their_node_id {
+                                       match chan.get_short_channel_id() {
+                                               Some(short_id) => {
+                                                       short_to_id.remove(&short_id);
+                                               },
+                                               None => {},
+                                       }
+                                       //TODO: get the latest commitment tx, any HTLC txn built on top of it, etc out
+                                       //of the channel and throw those into the announcement blackhole.
+                                       false
+                               } else {
+                                       true
+                               }
+                       });
+               } else {
+                       for chan in channel_state.by_id {
+                               if chan.1.get_their_node_id() == *their_node_id {
+                                       //TODO: mark channel disabled (and maybe announce such after a timeout). Also
+                                       //fail and wipe any uncommitted outbound HTLCs as those are considered after
+                                       //reconnect.
+                               }
+                       }
+               }
+       }
 }
 
 #[cfg(test)]
@@ -1496,7 +1528,7 @@ mod tests {
        use bitcoin::util::hash::Sha256dHash;
        use bitcoin::util::uint::Uint256;
        use bitcoin::blockdata::block::BlockHeader;
-       use bitcoin::blockdata::transaction::Transaction;
+       use bitcoin::blockdata::transaction::{Transaction, TxOut};
        use bitcoin::network::constants::Network;
        use bitcoin::network::serialize::serialize;
        use bitcoin::network::serialize::BitcoinHash;
@@ -1680,16 +1712,21 @@ mod tests {
                node_a.handle_accept_channel(&node_b.get_our_node_id(), &accept_chan).unwrap();
 
                let chan_id = unsafe { CHAN_COUNT };
-               let tx = Transaction { version: chan_id as u32, lock_time: 0, input: Vec::new(), output: Vec::new() };
-               let funding_output = (Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), chan_id);
+               let tx;
+               let funding_output;
 
                let events_1 = node_a.get_and_clear_pending_events();
                assert_eq!(events_1.len(), 1);
                match events_1[0] {
-                       Event::FundingGenerationReady { ref temporary_channel_id, ref channel_value_satoshis, output_script: _, user_channel_id } => {
+                       Event::FundingGenerationReady { ref temporary_channel_id, ref channel_value_satoshis, ref output_script, user_channel_id } => {
                                assert_eq!(*channel_value_satoshis, 100000);
                                assert_eq!(user_channel_id, 42);
 
+                               tx = Transaction { version: chan_id as u32, lock_time: 0, input: Vec::new(), output: vec![TxOut {
+                                       value: *channel_value_satoshis, script_pubkey: output_script.clone(),
+                               }]};
+                               funding_output = (Sha256dHash::from_data(&serialize(&tx).unwrap()[..]), 0);
+
                                node_a.funding_transaction_generated(&temporary_channel_id, funding_output.clone());
                                //TODO: Check that we got added to chan_monitor_a!
                        },