Merge pull request #74 from TheBlueMatt/2018-07-shutdown-event
[rust-lightning] / src / ln / channelmanager.rs
index 933fe217215860e8ddbd37a8827c4849224e24a0..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,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;
@@ -2010,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 {
@@ -2029,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();
@@ -2157,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());
@@ -2167,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());
@@ -2204,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()
                        },
@@ -2678,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 });
 
@@ -2792,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);
@@ -2807,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);
@@ -2848,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);
                }
@@ -2882,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);
                }
@@ -2902,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);
@@ -2914,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