Merge pull request #74 from TheBlueMatt/2018-07-shutdown-event
[rust-lightning] / src / ln / channelmanager.rs
index 6aeb7d353222058b11e0a9abc2d43cd2ff6e47ed..4c85bd0b0fd0d6423e678bdc5416c70634fe3988 100644 (file)
@@ -1,10 +1,9 @@
- use bitcoin::blockdata::block::BlockHeader;
+use bitcoin::blockdata::block::BlockHeader;
 use bitcoin::blockdata::transaction::Transaction;
 use bitcoin::blockdata::constants::genesis_block;
 use bitcoin::network::constants::Network;
 use bitcoin::network::serialize::BitcoinHash;
 use bitcoin::util::hash::Sha256dHash;
-use bitcoin::util::uint::Uint256;
 
 use secp256k1::key::{SecretKey,PublicKey};
 use secp256k1::{Secp256k1,Message};
@@ -111,16 +110,16 @@ enum PendingOutboundHTLC {
 const MIN_HTLC_RELAY_HOLDING_CELL_MILLIS: u32 = 50;
 
 struct ChannelHolder {
-       by_id: HashMap<Uint256, Channel>,
-       short_to_id: HashMap<u64, Uint256>,
+       by_id: HashMap<[u8; 32], Channel>,
+       short_to_id: HashMap<u64, [u8; 32]>,
        next_forward: Instant,
        /// short channel id -> forward infos. Key of 0 means payments received
        forward_htlcs: HashMap<u64, Vec<PendingForwardHTLCInfo>>,
        claimable_htlcs: HashMap<[u8; 32], PendingOutboundHTLC>,
 }
 struct MutChannelHolder<'a> {
-       by_id: &'a mut HashMap<Uint256, Channel>,
-       short_to_id: &'a mut HashMap<u64, Uint256>,
+       by_id: &'a mut HashMap<[u8; 32], Channel>,
+       short_to_id: &'a mut HashMap<u64, [u8; 32]>,
        next_forward: &'a mut Instant,
        /// short channel id -> forward infos. Key of 0 means payments received
        forward_htlcs: &'a mut HashMap<u64, Vec<PendingForwardHTLCInfo>>,
@@ -167,7 +166,7 @@ macro_rules! secp_call {
                match $res {
                        Ok(key) => key,
                        //TODO: Make the err a parameter!
-                       Err(_) => return Err(HandleError{err: "Key error", msg: None})
+                       Err(_) => return Err(HandleError{err: "Key error", action: None})
                }
        };
 }
@@ -187,7 +186,7 @@ pub struct ChannelDetails {
        /// thereafter this is the txid of the funding transaction xor the funding transaction output).
        /// Note that this means this value is *not* persistent - it can change once during the
        /// lifetime of the channel.
-       pub channel_id: Uint256,
+       pub channel_id: [u8; 32],
        /// The position of the funding transaction in the chain. None if the funding transaction has
        /// not yet been confirmed and the channel fully opened.
        pub short_channel_id: Option<u64>,
@@ -202,7 +201,7 @@ impl ChannelManager {
        /// the main "logic hub" for all channel-related actions, and implements ChannelMessageHandler.
        /// fee_proportional_millionths is an optional fee to charge any payments routed through us.
        /// Non-proportional fees are fixed according to our risk using the provided fee estimator.
-       /// panics if channel_value_satoshis is >= (1 << 24)!
+       /// panics if channel_value_satoshis is >= `MAX_FUNDING_SATOSHIS`!
        pub fn new(our_network_key: SecretKey, fee_proportional_millionths: u32, announce_channels_publicly: bool, network: Network, feeest: Arc<FeeEstimator>, monitor: Arc<ManyChannelMonitor>, chain_monitor: Arc<ChainWatchInterface>, tx_broadcaster: Arc<BroadcasterInterface>) -> Result<Arc<ChannelManager>, secp256k1::Error> {
                let secp_ctx = Secp256k1::new();
 
@@ -233,7 +232,14 @@ impl ChannelManager {
                Ok(res)
        }
 
-       pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, user_id: u64) -> Result<msgs::OpenChannel, HandleError> {
+       /// 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 and
+       /// FundingBroadcastSafe events to allow tracking of which events correspond with which
+       /// create_channel call. Note that user_channel_id defaults to 0 for inbound channels, so you
+       /// may wish to avoid using 0 for user_id here.
+       /// If successful, will generate a SendOpenChannel event, so you should probably poll
+       /// PeerManager::process_events afterwards.
+       pub fn create_channel(&self, their_network_key: PublicKey, channel_value_satoshis: u64, user_id: u64) -> Result<(), HandleError> {
                let chan_keys = if cfg!(feature = "fuzztarget") {
                        ChannelKeys {
                                funding_key:               SecretKey::from_slice(&self.secp_ctx, &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]).unwrap(),
@@ -259,8 +265,15 @@ impl ChannelManager {
                let mut channel_state = self.channel_state.lock().unwrap();
                match channel_state.by_id.insert(channel.channel_id(), channel) {
                        Some(_) => panic!("RNG is bad???"),
-                       None => Ok(res)
+                       None => {}
                }
+
+               let mut events = self.pending_events.lock().unwrap();
+               events.push(events::Event::SendOpenChannel {
+                       node_id: their_network_key,
+                       msg: res,
+               });
+               Ok(())
        }
 
        /// Gets the list of open channels, in random order. See ChannelDetail field documentation for
@@ -283,8 +296,9 @@ impl ChannelManager {
        /// Begins the process of closing a channel. After this call (plus some timeout), no new HTLCs
        /// will be accepted on the given channel, and after additional timeout/the closing of all
        /// pending HTLCs, the channel will be closed on chain.
-       pub fn close_channel(&self, channel_id: &Uint256) -> Result<msgs::Shutdown, HandleError> {
-               let (res, chan_option) = {
+       /// May generate a SendShutdown event on success, which should be relayed.
+       pub fn close_channel(&self, channel_id: &[u8; 32]) -> Result<(), HandleError> {
+               let (res, node_id, chan_option) = {
                        let mut channel_state_lock = self.channel_state.lock().unwrap();
                        let channel_state = channel_state_lock.borrow_parts();
                        match channel_state.by_id.entry(channel_id.clone()) {
@@ -294,25 +308,34 @@ impl ChannelManager {
                                                if let Some(short_id) = chan_entry.get().get_short_channel_id() {
                                                        channel_state.short_to_id.remove(&short_id);
                                                }
-                                               (res, Some(chan_entry.remove_entry().1))
-                                       } else { (res, None) }
+                                               (res, chan_entry.get().get_their_node_id(), Some(chan_entry.remove_entry().1))
+                                       } else { (res, chan_entry.get().get_their_node_id(), None) }
                                },
-                               hash_map::Entry::Vacant(_) => return Err(HandleError{err: "No such channel", msg: None})
+                               hash_map::Entry::Vacant(_) => return Err(HandleError{err: "No such channel", action: None})
                        }
                };
                for payment_hash in res.1 {
                        // unknown_next_peer...I dunno who that is anymore....
                        self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), &payment_hash, HTLCFailReason::Reason { failure_code: 0x4000 | 10, data: Vec::new() });
                }
-               if let Some(chan) = chan_option {
+               let chan_update = if let Some(chan) = chan_option {
                        if let Ok(update) = self.get_channel_update(&chan) {
-                               let mut events = self.pending_events.lock().unwrap();
-                               events.push(events::Event::BroadcastChannelUpdate {
-                                       msg: update
-                               });
-                       }
+                               Some(update)
+                       } else { None }
+               } else { None };
+
+               let mut events = self.pending_events.lock().unwrap();
+               if let Some(update) = chan_update {
+                       events.push(events::Event::BroadcastChannelUpdate {
+                               msg: update
+                       });
                }
-               Ok(res.0)
+               events.push(events::Event::SendShutdown {
+                       node_id,
+                       msg: res.0
+               });
+
+               Ok(())
        }
 
        #[inline]
@@ -429,11 +452,11 @@ impl ChannelManager {
                        };
                        cur_value_msat += hop.fee_msat;
                        if cur_value_msat >= 21000000 * 100000000 * 1000 {
-                               return Err(HandleError{err: "Channel fees overflowed?!", msg: None});
+                               return Err(HandleError{err: "Channel fees overflowed?!", action: None});
                        }
                        cur_cltv += hop.cltv_expiry_delta as u32;
                        if cur_cltv >= 500000000 {
-                               return Err(HandleError{err: "Channel CLTV overflowed?!", msg: None});
+                               return Err(HandleError{err: "Channel CLTV overflowed?!", action: None});
                        }
                        last_short_channel_id = hop.short_channel_id;
                }
@@ -562,7 +585,7 @@ impl ChannelManager {
        /// only fails if the channel does not yet have an assigned short_id
        fn get_channel_update(&self, chan: &Channel) -> Result<msgs::ChannelUpdate, HandleError> {
                let short_channel_id = match chan.get_short_channel_id() {
-                       None => return Err(HandleError{err: "Channel not yet established", msg: None}),
+                       None => return Err(HandleError{err: "Channel not yet established", action: None}),
                        Some(id) => id,
                };
 
@@ -595,12 +618,12 @@ impl ChannelManager {
        /// May generate a SendHTLCs event on success, which should be relayed.
        pub fn send_payment(&self, route: Route, payment_hash: [u8; 32]) -> Result<(), HandleError> {
                if route.hops.len() < 1 || route.hops.len() > 20 {
-                       return Err(HandleError{err: "Route didn't go anywhere/had bogus size", msg: None});
+                       return Err(HandleError{err: "Route didn't go anywhere/had bogus size", action: None});
                }
                let our_node_id = self.get_our_node_id();
                for (idx, hop) in route.hops.iter().enumerate() {
                        if idx != route.hops.len() - 1 && hop.pubkey == our_node_id {
-                               return Err(HandleError{err: "Route went through us but wasn't a simple rebalance loop to us", msg: None});
+                               return Err(HandleError{err: "Route went through us but wasn't a simple rebalance loop to us", action: None});
                        }
                }
 
@@ -619,13 +642,13 @@ impl ChannelManager {
                let (first_hop_node_id, (update_add, commitment_signed, chan_monitor)) = {
                        let mut channel_state = self.channel_state.lock().unwrap();
                        let id = match channel_state.short_to_id.get(&route.hops.first().unwrap().short_channel_id) {
-                               None => return Err(HandleError{err: "No channel available with first hop!", msg: None}),
+                               None => return Err(HandleError{err: "No channel available with first hop!", action: None}),
                                Some(id) => id.clone()
                        };
                        let res = {
                                let chan = channel_state.by_id.get_mut(&id).unwrap();
                                if chan.get_their_node_id() != route.hops.first().unwrap().pubkey {
-                                       return Err(HandleError{err: "Node ID mismatch on first hop!", msg: None});
+                                       return Err(HandleError{err: "Node ID mismatch on first hop!", action: None});
                                }
                                chan.send_htlc_and_commit(htlc_msat, payment_hash.clone(), htlc_cltv, onion_packet)?
                        };
@@ -662,10 +685,10 @@ impl ChannelManager {
 
        /// Call this upon creation of a funding transaction for the given channel.
        /// Panics if a funding transaction has already been provided for this channel.
-       pub fn funding_transaction_generated(&self, temporary_channel_id: &Uint256, funding_txo: OutPoint) {
+       pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], funding_txo: OutPoint) {
                let (chan, msg, chan_monitor) = {
                        let mut channel_state = self.channel_state.lock().unwrap();
-                       match channel_state.by_id.remove(&temporary_channel_id) {
+                       match channel_state.by_id.remove(temporary_channel_id) {
                                Some(mut chan) => {
                                        match chan.get_outbound_funding_created(funding_txo) {
                                                Ok(funding_msg) => {
@@ -696,7 +719,7 @@ impl ChannelManager {
        }
 
        fn get_announcement_sigs(&self, chan: &Channel) -> Result<Option<msgs::AnnouncementSignatures>, HandleError> {
-               if !chan.is_usable() { return Ok(None) }
+               if !chan.is_usable() || !chan.should_announce() { return Ok(None) }
 
                let (announcement, our_bitcoin_sig) = chan.get_channel_announcement(self.get_our_node_id(), self.genesis_hash.clone())?;
                let msghash = Message::from_slice(&Sha256dHash::from_data(&announcement.encode()[..])[..]).unwrap();
@@ -730,7 +753,6 @@ impl ChannelManager {
                                                        for forward_info in pending_forwards {
                                                                failed_forwards.push((forward_info.payment_hash, 0x4000 | 10, None));
                                                        }
-                                                       // TODO: Send a failure packet back on each pending_forward
                                                        continue;
                                                }
                                        };
@@ -741,7 +763,7 @@ impl ChannelManager {
                                                match forward_chan.send_htlc(forward_info.amt_to_forward, forward_info.payment_hash, forward_info.outgoing_cltv_value, forward_info.onion_packet.unwrap()) {
                                                        Err(_e) => {
                                                                let chan_update = self.get_channel_update(forward_chan).unwrap();
-                                                               failed_forwards.push((forward_info.payment_hash, 0x4000 | 7, Some(chan_update)));
+                                                               failed_forwards.push((forward_info.payment_hash, 0x1000 | 7, Some(chan_update)));
                                                                continue;
                                                        },
                                                        Ok(update_add) => {
@@ -1072,13 +1094,25 @@ impl ChainListener for ChannelManager {
                }
        }
 
+       /// We force-close the channel without letting our counterparty participate in the shutdown
        fn block_disconnected(&self, header: &BlockHeader) {
-               let mut channel_state = self.channel_state.lock().unwrap();
-               for channel in channel_state.by_id.values_mut() {
-                       if channel.block_disconnected(header) {
-                               //TODO Close channel here
+               let mut channel_lock = self.channel_state.lock().unwrap();
+               let channel_state = channel_lock.borrow_parts();
+               let short_to_id = channel_state.short_to_id;
+               channel_state.by_id.retain(|_,  v| {
+                       if v.block_disconnected(header) {
+                               let tx = v.force_shutdown();
+                               for broadcast_tx in tx {
+                                       self.tx_broadcaster.broadcast_transaction(&broadcast_tx);
+                               }
+                               if let Some(short_id) = v.get_short_channel_id() {
+                                       short_to_id.remove(&short_id);
+                               }
+                               false
+                       } else {
+                               true
                        }
-               }
+               });
        }
 }
 
@@ -1086,11 +1120,11 @@ impl ChannelMessageHandler for ChannelManager {
        //TODO: Handle errors and close channel (or so)
        fn handle_open_channel(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannel) -> Result<msgs::AcceptChannel, HandleError> {
                if msg.chain_hash != self.genesis_hash {
-                       return Err(HandleError{err: "Unknown genesis block hash", msg: None});
+                       return Err(HandleError{err: "Unknown genesis block hash", action: None});
                }
                let mut channel_state = self.channel_state.lock().unwrap();
                if channel_state.by_id.contains_key(&msg.temporary_channel_id) {
-                       return Err(HandleError{err: "temporary_channel_id collision!", msg: None});
+                       return Err(HandleError{err: "temporary_channel_id collision!", action: None});
                }
 
                let chan_keys = if cfg!(feature = "fuzztarget") {
@@ -1125,12 +1159,12 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.get_mut(&msg.temporary_channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        chan.accept_channel(&msg)?;
                                        (chan.get_value_satoshis(), chan.get_funding_redeemscript().to_v0_p2wsh(), chan.get_user_id())
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                let mut pending_events = self.pending_events.lock().unwrap();
@@ -1152,7 +1186,7 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.remove(&msg.temporary_channel_id) {
                                Some(mut chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        match chan.funding_created(msg) {
                                                Ok((funding_msg, monitor_update)) => {
@@ -1163,7 +1197,7 @@ impl ChannelMessageHandler for ChannelManager {
                                                }
                                        }
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                }; // Release channel lock for install_watch_outpoint call,
                   // note that this means if the remote end is misbehaving and sends a message for the same
@@ -1183,12 +1217,12 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        let chan_monitor = chan.funding_signed(&msg)?;
                                        (chan.get_funding_txo().unwrap(), chan.get_user_id(), chan_monitor)
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
@@ -1207,12 +1241,12 @@ impl ChannelMessageHandler for ChannelManager {
                match channel_state.by_id.get_mut(&msg.channel_id) {
                        Some(chan) => {
                                if chan.get_their_node_id() != *their_node_id {
-                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                }
                                chan.funding_locked(&msg)?;
                                return Ok(self.get_announcement_sigs(chan)?);
                        },
-                       None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                       None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                };
        }
 
@@ -1224,7 +1258,7 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.entry(msg.channel_id.clone()) {
                                hash_map::Entry::Occupied(mut chan_entry) => {
                                        if chan_entry.get().get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        let res = chan_entry.get_mut().shutdown(&*self.fee_estimator, &msg)?;
                                        if chan_entry.get().is_shutdown() {
@@ -1234,7 +1268,7 @@ impl ChannelMessageHandler for ChannelManager {
                                                (res, Some(chan_entry.remove_entry().1))
                                        } else { (res, None) }
                                },
-                               hash_map::Entry::Vacant(_) => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               hash_map::Entry::Vacant(_) => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                for payment_hash in res.2 {
@@ -1259,7 +1293,7 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.entry(msg.channel_id.clone()) {
                                hash_map::Entry::Occupied(mut chan_entry) => {
                                        if chan_entry.get().get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        let res = chan_entry.get_mut().closing_signed(&*self.fee_estimator, &msg)?;
                                        if res.1.is_some() {
@@ -1274,7 +1308,7 @@ impl ChannelMessageHandler for ChannelManager {
                                                (res, Some(chan_entry.remove_entry().1))
                                        } else { (res, None) }
                                },
-                               hash_map::Entry::Vacant(_) => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               hash_map::Entry::Vacant(_) => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                if let Some(broadcast_tx) = res.1 {
@@ -1322,7 +1356,7 @@ impl ChannelMessageHandler for ChannelManager {
                        ($msg: expr, $err_code: expr, $data: expr) => {
                                return Err(msgs::HandleError {
                                        err: $msg,
-                                       msg: Some(msgs::ErrorAction::UpdateFailHTLC {
+                                       action: Some(msgs::ErrorAction::UpdateFailHTLC {
                                                msg: msgs::UpdateFailHTLC {
                                                        channel_id: msg.channel_id,
                                                        htlc_id: msg.htlc_id,
@@ -1452,7 +1486,7 @@ impl ChannelMessageHandler for ChannelManager {
                        let chan = channel_state.by_id.get_mut(&forwarding_id).unwrap();
                        if !chan.is_live() {
                                let chan_update = self.get_channel_update(chan).unwrap();
-                               return_err!("Forwarding channel is not in a ready state.", 0x4000 | 7, &chan_update.encode_with_len()[..]);
+                               return_err!("Forwarding channel is not in a ready state.", 0x1000 | 7, &chan_update.encode_with_len()[..]);
                        }
                }
 
@@ -1481,16 +1515,16 @@ impl ChannelMessageHandler for ChannelManager {
                let (source_short_channel_id, res) = match channel_state.by_id.get_mut(&msg.channel_id) {
                        Some(chan) => {
                                if chan.get_their_node_id() != *their_node_id {
-                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                }
                                if !chan.is_usable() {
-                                       return Err(HandleError{err: "Channel not yet available for receiving HTLCs", msg: None});
+                                       return Err(HandleError{err: "Channel not yet available for receiving HTLCs", action: None});
                                }
                                let short_channel_id = chan.get_short_channel_id().unwrap();
                                pending_forward_info.prev_short_channel_id = short_channel_id;
                                (short_channel_id, chan.update_add_htlc(&msg, pending_forward_info)?)
                        },
-                       None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None}), //TODO: panic?
+                       None => return Err(HandleError{err: "Failed to find corresponding channel", action: None}), //TODO: panic?
                };
 
                match claimable_htlcs_entry {
@@ -1531,11 +1565,11 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        chan.update_fulfill_htlc(&msg)?
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                if let Err(_e) = self.monitor.add_update_monitor(monitor.get_funding_txo().unwrap(), monitor) {
@@ -1549,11 +1583,11 @@ impl ChannelMessageHandler for ChannelManager {
                let payment_hash = match channel_state.by_id.get_mut(&msg.channel_id) {
                        Some(chan) => {
                                if chan.get_their_node_id() != *their_node_id {
-                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                }
                                chan.update_fail_htlc(&msg, HTLCFailReason::ErrorPacket { err: msg.reason.clone() })
                        },
-                       None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                       None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                }?;
 
                if let Some(pending_htlc) = channel_state.claimable_htlcs.get(&payment_hash) {
@@ -1624,11 +1658,11 @@ impl ChannelMessageHandler for ChannelManager {
                match channel_state.by_id.get_mut(&msg.channel_id) {
                        Some(chan) => {
                                if chan.get_their_node_id() != *their_node_id {
-                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                }
                                chan.update_fail_malformed_htlc(&msg, HTLCFailReason::Reason { failure_code: msg.failure_code, data: Vec::new() })
                        },
-                       None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                       None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                }
        }
 
@@ -1638,11 +1672,11 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        chan.commitment_signed(&msg)?
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
@@ -1658,11 +1692,11 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        chan.revoke_and_ack(&msg)?
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
@@ -1708,11 +1742,11 @@ impl ChannelMessageHandler for ChannelManager {
                match channel_state.by_id.get_mut(&msg.channel_id) {
                        Some(chan) => {
                                if chan.get_their_node_id() != *their_node_id {
-                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                       return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                }
                                chan.update_fee(&*self.fee_estimator, &msg)
                        },
-                       None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                       None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                }
        }
 
@@ -1722,10 +1756,10 @@ impl ChannelMessageHandler for ChannelManager {
                        match channel_state.by_id.get_mut(&msg.channel_id) {
                                Some(chan) => {
                                        if chan.get_their_node_id() != *their_node_id {
-                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", msg: None})
+                                               return Err(HandleError{err: "Got a message for a channel from the wrong node!", action: None})
                                        }
                                        if !chan.is_usable() {
-                                               return Err(HandleError{err: "Got an announcement_signatures before we were ready for it", msg: None });
+                                               return Err(HandleError{err: "Got an announcement_signatures before we were ready for it", action: None });
                                        }
 
                                        let our_node_id = self.get_our_node_id();
@@ -1746,7 +1780,7 @@ impl ChannelMessageHandler for ChannelManager {
                                                contents: announcement,
                                        }, self.get_channel_update(chan).unwrap()) // can only fail if we're not in a ready state
                                },
-                               None => return Err(HandleError{err: "Failed to find corresponding channel", msg: None})
+                               None => return Err(HandleError{err: "Failed to find corresponding channel", action: None})
                        }
                };
                let mut pending_events = self.pending_events.lock().unwrap();
@@ -1803,6 +1837,7 @@ impl ChannelMessageHandler for ChannelManager {
 mod tests {
        use chain::chaininterface;
        use chain::transaction::OutPoint;
+       use chain::chaininterface::ChainListener;
        use ln::channelmanager::{ChannelManager,OnionKeys};
        use ln::router::{Route, RouteHop, Router};
        use ln::msgs;
@@ -1812,8 +1847,7 @@ mod tests {
 
        use bitcoin::util::misc::hex_bytes;
        use bitcoin::util::hash::Sha256dHash;
-       use bitcoin::util::uint::Uint256;
-       use bitcoin::blockdata::block::BlockHeader;
+       use bitcoin::blockdata::block::{Block, BlockHeader};
        use bitcoin::blockdata::transaction::{Transaction, TxOut};
        use bitcoin::network::constants::Network;
        use bitcoin::network::serialize::serialize;
@@ -1984,6 +2018,7 @@ mod tests {
        }
 
        fn confirm_transaction(chain: &chaininterface::ChainWatchInterfaceUtil, tx: &Transaction, chan_id: u32) {
+               assert!(chain.does_match_tx(tx));
                let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
                chain.block_connected_checked(&header, 1, &[tx; 1], &[chan_id; 1]);
                for i in 2..100 {
@@ -2003,18 +2038,28 @@ mod tests {
        }
 
        static mut CHAN_COUNT: u32 = 0;
-       fn create_chan_between_nodes(node_a: &Node, node_b: &Node) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, Uint256, Transaction) {
-               let open_chan = node_a.node.create_channel(node_b.node.get_our_node_id(), 100000, 42).unwrap();
-               let accept_chan = node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), &open_chan).unwrap();
+       fn create_chan_between_nodes(node_a: &Node, node_b: &Node) -> (msgs::ChannelAnnouncement, msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
+               node_a.node.create_channel(node_b.node.get_our_node_id(), 100000, 42).unwrap();
+
+               let events_1 = node_a.node.get_and_clear_pending_events();
+               assert_eq!(events_1.len(), 1);
+               let accept_chan = match events_1[0] {
+                       Event::SendOpenChannel { ref node_id, ref msg } => {
+                               assert_eq!(*node_id, node_b.node.get_our_node_id());
+                               node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), msg).unwrap()
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+
                node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), &accept_chan).unwrap();
 
                let chan_id = unsafe { CHAN_COUNT };
                let tx;
                let funding_output;
 
-               let events_1 = node_a.node.get_and_clear_pending_events();
-               assert_eq!(events_1.len(), 1);
-               match events_1[0] {
+               let events_2 = node_a.node.get_and_clear_pending_events();
+               assert_eq!(events_2.len(), 1);
+               match events_2[0] {
                        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);
@@ -2033,9 +2078,9 @@ mod tests {
                        _ => panic!("Unexpected event"),
                }
 
-               let events_2 = node_a.node.get_and_clear_pending_events();
-               assert_eq!(events_2.len(), 1);
-               let funding_signed = match events_2[0] {
+               let events_3 = node_a.node.get_and_clear_pending_events();
+               assert_eq!(events_3.len(), 1);
+               let funding_signed = match events_3[0] {
                        Event::SendFundingCreated { ref node_id, ref msg } => {
                                assert_eq!(*node_id, node_b.node.get_our_node_id());
                                let res = node_b.node.handle_funding_created(&node_a.node.get_our_node_id(), msg).unwrap();
@@ -2056,9 +2101,9 @@ mod tests {
                        added_monitors.clear();
                }
 
-               let events_3 = node_a.node.get_and_clear_pending_events();
-               assert_eq!(events_3.len(), 1);
-               match events_3[0] {
+               let events_4 = node_a.node.get_and_clear_pending_events();
+               assert_eq!(events_4.len(), 1);
+               match events_4[0] {
                        Event::FundingBroadcastSafe { ref funding_txo, user_channel_id } => {
                                assert_eq!(user_channel_id, 42);
                                assert_eq!(*funding_txo, funding_output);
@@ -2067,9 +2112,9 @@ mod tests {
                };
 
                confirm_transaction(&node_a.chain_monitor, &tx, chan_id);
-               let events_4 = node_a.node.get_and_clear_pending_events();
-               assert_eq!(events_4.len(), 1);
-               match events_4[0] {
+               let events_5 = node_a.node.get_and_clear_pending_events();
+               assert_eq!(events_5.len(), 1);
+               match events_5[0] {
                        Event::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => {
                                assert_eq!(*node_id, node_b.node.get_our_node_id());
                                assert!(announcement_sigs.is_none());
@@ -2081,9 +2126,9 @@ mod tests {
                let channel_id;
 
                confirm_transaction(&node_b.chain_monitor, &tx, chan_id);
-               let events_5 = node_b.node.get_and_clear_pending_events();
-               assert_eq!(events_5.len(), 1);
-               let as_announcement_sigs = match events_5[0] {
+               let events_6 = node_b.node.get_and_clear_pending_events();
+               assert_eq!(events_6.len(), 1);
+               let as_announcement_sigs = match events_6[0] {
                        Event::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => {
                                assert_eq!(*node_id, node_a.node.get_our_node_id());
                                channel_id = msg.channel_id.clone();
@@ -2094,9 +2139,9 @@ mod tests {
                        _ => panic!("Unexpected event"),
                };
 
-               let events_6 = node_a.node.get_and_clear_pending_events();
-               assert_eq!(events_6.len(), 1);
-               let (announcement, as_update) = match events_6[0] {
+               let events_7 = node_a.node.get_and_clear_pending_events();
+               assert_eq!(events_7.len(), 1);
+               let (announcement, as_update) = match events_7[0] {
                        Event::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
                                (msg, update_msg)
                        },
@@ -2104,9 +2149,9 @@ mod tests {
                };
 
                node_b.node.handle_announcement_signatures(&node_a.node.get_our_node_id(), &as_announcement_sigs).unwrap();
-               let events_7 = node_b.node.get_and_clear_pending_events();
-               assert_eq!(events_7.len(), 1);
-               let bs_update = match events_7[0] {
+               let events_8 = node_b.node.get_and_clear_pending_events();
+               assert_eq!(events_8.len(), 1);
+               let bs_update = match events_8[0] {
                        Event::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
                                assert!(*announcement == *msg);
                                update_msg
@@ -2121,7 +2166,7 @@ mod tests {
                ((*announcement).clone(), (*as_update).clone(), (*bs_update).clone(), channel_id, tx)
        }
 
-       fn create_announced_chan_between_nodes(nodes: &Vec<Node>, a: usize, b: usize) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, Uint256, Transaction) {
+       fn create_announced_chan_between_nodes(nodes: &Vec<Node>, a: usize, b: usize) -> (msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction) {
                let chan_announcement = create_chan_between_nodes(&nodes[a], &nodes[b]);
                for node in nodes {
                        assert!(node.router.handle_channel_announcement(&chan_announcement.0).unwrap());
@@ -2131,12 +2176,22 @@ mod tests {
                (chan_announcement.1, chan_announcement.2, chan_announcement.3, chan_announcement.4)
        }
 
-       fn close_channel(outbound_node: &Node, inbound_node: &Node, channel_id: &Uint256, funding_tx: Transaction, close_inbound_first: bool) -> (msgs::ChannelUpdate, msgs::ChannelUpdate) {
+       fn close_channel(outbound_node: &Node, inbound_node: &Node, channel_id: &[u8; 32], funding_tx: Transaction, close_inbound_first: bool) -> (msgs::ChannelUpdate, msgs::ChannelUpdate) {
                let (node_a, broadcaster_a) = if close_inbound_first { (&inbound_node.node, &inbound_node.tx_broadcaster) } else { (&outbound_node.node, &outbound_node.tx_broadcaster) };
                let (node_b, broadcaster_b) = if close_inbound_first { (&outbound_node.node, &outbound_node.tx_broadcaster) } else { (&inbound_node.node, &inbound_node.tx_broadcaster) };
                let (tx_a, tx_b);
 
-               let shutdown_a = node_a.close_channel(channel_id).unwrap();
+               node_a.close_channel(channel_id).unwrap();
+               let events_1 = node_a.get_and_clear_pending_events();
+               assert_eq!(events_1.len(), 1);
+               let shutdown_a = match events_1[0] {
+                       Event::SendShutdown { ref node_id, ref msg } => {
+                               assert_eq!(node_id, &node_b.get_our_node_id());
+                               msg.clone()
+                       },
+                       _ => panic!("Unexpected event"),
+               };
+
                let (shutdown_b, mut closing_signed_b) = node_b.handle_shutdown(&node_a.get_our_node_id(), &shutdown_a).unwrap();
                if !close_inbound_first {
                        assert!(closing_signed_b.is_none());
@@ -2168,18 +2223,18 @@ mod tests {
                funding_tx_map.insert(funding_tx.txid(), funding_tx);
                tx_a.verify(&funding_tx_map).unwrap();
 
-               let events_1 = node_a.get_and_clear_pending_events();
-               assert_eq!(events_1.len(), 1);
-               let as_update = match events_1[0] {
+               let events_2 = node_a.get_and_clear_pending_events();
+               assert_eq!(events_2.len(), 1);
+               let as_update = match events_2[0] {
                        Event::BroadcastChannelUpdate { ref msg } => {
                                msg.clone()
                        },
                        _ => panic!("Unexpected event"),
                };
 
-               let events_2 = node_b.get_and_clear_pending_events();
-               assert_eq!(events_2.len(), 1);
-               let bs_update = match events_2[0] {
+               let events_3 = node_b.get_and_clear_pending_events();
+               assert_eq!(events_3.len(), 1);
+               let bs_update = match events_3[0] {
                        Event::BroadcastChannelUpdate { ref msg } => {
                                msg.clone()
                        },
@@ -2642,7 +2697,7 @@ mod tests {
 
        #[derive(PartialEq)]
        enum HTLCType { NONE, TIMEOUT, SUCCESS }
-       fn test_txn_broadcast(node: &Node, chan: &(msgs::ChannelUpdate, msgs::ChannelUpdate, Uint256, Transaction), commitment_tx: Option<Transaction>, has_htlc_tx: HTLCType) -> Vec<Transaction> {
+       fn test_txn_broadcast(node: &Node, chan: &(msgs::ChannelUpdate, msgs::ChannelUpdate, [u8; 32], Transaction), commitment_tx: Option<Transaction>, has_htlc_tx: HTLCType) -> Vec<Transaction> {
                let mut node_txn = node.tx_broadcaster.txn_broadcasted.lock().unwrap();
                assert!(node_txn.len() >= if commitment_tx.is_some() { 0 } else { 1 } + if has_htlc_tx == HTLCType::NONE { 0 } else { 1 });
 
@@ -2756,9 +2811,9 @@ mod tests {
                // Simple case with no pending HTLCs:
                nodes[1].node.peer_disconnected(&nodes[0].node.get_our_node_id(), true);
                {
-                       let node_txn = test_txn_broadcast(&nodes[1], &chan_1, None, HTLCType::NONE);
+                       let mut node_txn = test_txn_broadcast(&nodes[1], &chan_1, None, HTLCType::NONE);
                        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       nodes[0].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0]; 1], &[4; 1]);
+                       nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn.drain(..).next().unwrap()] }, 1);
                        assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0);
                }
                get_announce_close_broadcast_events(&nodes, 0, 1);
@@ -2771,9 +2826,9 @@ mod tests {
                // Simple case of one pending HTLC to HTLC-Timeout
                nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), true);
                {
-                       let node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::TIMEOUT);
+                       let mut node_txn = test_txn_broadcast(&nodes[1], &chan_2, None, HTLCType::TIMEOUT);
                        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       nodes[2].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0]; 1], &[4; 1]);
+                       nodes[2].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn.drain(..).next().unwrap()] }, 1);
                        assert_eq!(nodes[2].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 0);
                }
                get_announce_close_broadcast_events(&nodes, 1, 2);
@@ -2812,7 +2867,7 @@ mod tests {
                        claim_funds!(nodes[3], nodes[2], payment_preimage_1);
 
                        let header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       nodes[3].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[0]; 1], &[4; 1]);
+                       nodes[3].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()] }, 1);
 
                        check_preimage_claim(&nodes[3], &node_txn);
                }
@@ -2846,7 +2901,7 @@ mod tests {
                        test_txn_broadcast(&nodes[4], &chan_4, None, HTLCType::SUCCESS);
 
                        header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       nodes[4].chain_monitor.block_connected_checked(&header, TEST_FINAL_CLTV - 5, &[&node_txn[0]; 1], &[4; 1]);
+                       nodes[4].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[0].clone()] }, TEST_FINAL_CLTV - 5);
 
                        check_preimage_claim(&nodes[4], &node_txn);
                }
@@ -2866,7 +2921,7 @@ mod tests {
 
                {
                        let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       nodes[1].chain_monitor.block_connected_checked(&header, 1, &vec![&revoked_local_txn[0]; 1], &[4; 1]);
+                       nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
                        {
                                let mut node_txn = nodes[1].tx_broadcaster.txn_broadcasted.lock().unwrap();
                                assert_eq!(node_txn.len(), 1);
@@ -2878,10 +2933,10 @@ mod tests {
                                node_txn.clear();
                        }
 
-                       nodes[0].chain_monitor.block_connected_checked(&header, 1, &vec![&revoked_local_txn[0]; 1], &[4; 0]);
+                       nodes[0].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![revoked_local_txn[0].clone()] }, 1);
                        let node_txn = test_txn_broadcast(&nodes[0], &chan_5, Some(revoked_local_txn[0].clone()), HTLCType::TIMEOUT);
                        header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
-                       nodes[1].chain_monitor.block_connected_checked(&header, 1, &[&node_txn[1]; 1], &[4; 1]);
+                       nodes[1].chain_monitor.block_connected_with_filtering(&Block { header, txdata: vec![node_txn[1].clone()] }, 1);
 
                        //TODO: At this point nodes[1] should claim the revoked HTLC-Timeout output, but that's
                        //not yet implemented in ChannelMonitor
@@ -2896,4 +2951,30 @@ mod tests {
                        assert_eq!(node.chan_monitor.added_monitors.lock().unwrap().len(), 0);
                }
        }
+
+       #[test]
+       fn test_unconf_chan() {
+               // After creating a chan between nodes, we disconnect all blocks previously seen to force a channel close on nodes[0] side
+               let nodes = create_network(2);
+               create_announced_chan_between_nodes(&nodes, 0, 1);
+
+               let channel_state = nodes[0].node.channel_state.lock().unwrap();
+               assert_eq!(channel_state.by_id.len(), 1);
+               assert_eq!(channel_state.short_to_id.len(), 1);
+               mem::drop(channel_state);
+
+               let mut headers = Vec::new();
+               let mut header = BlockHeader { version: 0x20000000, prev_blockhash: Default::default(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+               headers.push(header.clone());
+               for _i in 2..100 {
+                       header = BlockHeader { version: 0x20000000, prev_blockhash: header.bitcoin_hash(), merkle_root: Default::default(), time: 42, bits: 42, nonce: 42 };
+                       headers.push(header.clone());
+               }
+               while !headers.is_empty() {
+                       nodes[0].node.block_disconnected(&headers.pop().unwrap());
+               }
+               let channel_state = nodes[0].node.channel_state.lock().unwrap();
+               assert_eq!(channel_state.by_id.len(), 0);
+               assert_eq!(channel_state.short_to_id.len(), 0);
+       }
 }