Merge pull request #74 from TheBlueMatt/2018-07-shutdown-event
[rust-lightning] / src / ln / channelmanager.rs
index b17dcd8198f086ad4b5202c18e38776d4095c987..4c85bd0b0fd0d6423e678bdc5416c70634fe3988 100644 (file)
@@ -4,7 +4,6 @@ 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>>,
@@ -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>,
@@ -297,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()) {
@@ -308,8 +308,8 @@ 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", action: None})
                        }
@@ -318,15 +318,24 @@ impl ChannelManager {
                        // 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]
@@ -676,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) => {
@@ -710,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();
@@ -1838,7 +1847,6 @@ mod tests {
 
        use bitcoin::util::misc::hex_bytes;
        use bitcoin::util::hash::Sha256dHash;
-       use bitcoin::util::uint::Uint256;
        use bitcoin::blockdata::block::{Block, BlockHeader};
        use bitcoin::blockdata::transaction::{Transaction, TxOut};
        use bitcoin::network::constants::Network;
@@ -2030,7 +2038,7 @@ 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) {
+       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();
@@ -2158,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());
@@ -2168,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());
@@ -2205,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()
                        },
@@ -2679,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 });