Add test_invalid_channel_announcemnt + test utilities
authorAntoine Riard <ariard@student.42.fr>
Thu, 30 Aug 2018 01:42:11 +0000 (01:42 +0000)
committerMatt Corallo <git@bluematt.me>
Mon, 3 Sep 2018 21:40:12 +0000 (17:40 -0400)
Fix typo

src/chain/transaction.rs
src/ln/channel.rs
src/ln/channelmanager.rs
src/ln/router.rs

index f89b6080600a46b32bcbc5afc4ff66cafdd39c42..227afa0de68e35bf8a104ea913f6ce7e2c6b0db0 100644 (file)
@@ -13,7 +13,7 @@ pub struct OutPoint {
 }
 
 impl OutPoint {
-       /// Creates a new `OutPoint` from the txid an the index.
+       /// Creates a new `OutPoint` from the txid and the index.
        pub fn new(txid: Sha256dHash, index: u16) -> OutPoint {
                OutPoint { txid, index }
        }
index 14a5589e7891ab661f275c74e8e292077b4d83c3..a15bbd813b706a2f7d3e4af2a8abb70a3b4540e3 100644 (file)
@@ -2002,6 +2002,12 @@ impl Channel {
                self.channel_value_satoshis
        }
 
+       //TODO: Testing purpose only, should be changed in another way after #81
+       #[cfg(test)]
+       pub fn get_local_keys(&self) -> &ChannelKeys {
+               &self.local_keys
+       }
+
        /// Allowed in any state (including after shutdown)
        pub fn get_channel_update_count(&self) -> u32 {
                self.channel_update_count
index 2c28e595e270030bada951faad448734f7c7ae5d..2bcf90d9631952433c1654e048e976421fd6386d 100644 (file)
@@ -2093,13 +2093,14 @@ mod tests {
        use bitcoin::util::hash::Sha256dHash;
        use bitcoin::blockdata::block::{Block, BlockHeader};
        use bitcoin::blockdata::transaction::{Transaction, TxOut};
+       use bitcoin::blockdata::constants::genesis_block;
        use bitcoin::network::constants::Network;
        use bitcoin::network::serialize::serialize;
        use bitcoin::network::serialize::BitcoinHash;
 
        use hex;
 
-       use secp256k1::Secp256k1;
+       use secp256k1::{Secp256k1, Message};
        use secp256k1::key::{PublicKey,SecretKey};
 
        use crypto::sha2::Sha256;
@@ -3235,4 +3236,78 @@ mod tests {
                assert_eq!(channel_state.by_id.len(), 0);
                assert_eq!(channel_state.short_to_id.len(), 0);
        }
+
+       #[test]
+       fn test_invalid_channel_announcement() {
+               //Test BOLT 7 channel_announcement msg requirement for final node, gather data to build customed channel_announcement msgs
+               let secp_ctx = Secp256k1::new();
+               let nodes = create_network(2);
+
+               let chan_announcement = create_chan_between_nodes(&nodes[0], &nodes[1]);
+
+               let a_channel_lock = nodes[0].node.channel_state.lock().unwrap();
+               let b_channel_lock = nodes[1].node.channel_state.lock().unwrap();
+               let as_chan = a_channel_lock.by_id.get(&chan_announcement.3).unwrap();
+               let bs_chan = b_channel_lock.by_id.get(&chan_announcement.3).unwrap();
+
+               let _ = nodes[0].router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id : as_chan.get_short_channel_id().unwrap() } );
+
+               let as_bitcoin_key = PublicKey::from_secret_key(&secp_ctx, &as_chan.get_local_keys().funding_key);
+               let bs_bitcoin_key = PublicKey::from_secret_key(&secp_ctx, &bs_chan.get_local_keys().funding_key);
+
+               let as_network_key = nodes[0].node.get_our_node_id();
+               let bs_network_key = nodes[1].node.get_our_node_id();
+
+               let were_node_one = as_bitcoin_key.serialize()[..] < bs_bitcoin_key.serialize()[..];
+
+               let mut chan_announcement;
+
+               macro_rules! dummy_unsigned_msg {
+                       () => {
+                               msgs::UnsignedChannelAnnouncement {
+                                       features: msgs::GlobalFeatures::new(),
+                                       chain_hash: genesis_block(Network::Testnet).header.bitcoin_hash(),
+                                       short_channel_id: as_chan.get_short_channel_id().unwrap(),
+                                       node_id_1: if were_node_one { as_network_key } else { bs_network_key },
+                                       node_id_2: if !were_node_one { bs_network_key } else { as_network_key },
+                                       bitcoin_key_1: if were_node_one { as_bitcoin_key } else { bs_bitcoin_key },
+                                       bitcoin_key_2: if !were_node_one { bs_bitcoin_key } else { as_bitcoin_key },
+                                       excess_data: Vec::new(),
+                               };
+                       }
+               }
+
+               macro_rules! sign_msg {
+                       ($unsigned_msg: expr) => {
+                               let msghash = Message::from_slice(&Sha256dHash::from_data(&$unsigned_msg.encode()[..])[..]).unwrap();
+                               let as_bitcoin_sig = secp_ctx.sign(&msghash, &as_chan.get_local_keys().funding_key);
+                               let bs_bitcoin_sig = secp_ctx.sign(&msghash, &bs_chan.get_local_keys().funding_key);
+                               let as_node_sig = secp_ctx.sign(&msghash, &nodes[0].node.our_network_key);
+                               let bs_node_sig = secp_ctx.sign(&msghash, &nodes[1].node.our_network_key);
+                               chan_announcement = msgs::ChannelAnnouncement {
+                                       node_signature_1 : if were_node_one { as_node_sig } else { bs_node_sig},
+                                       node_signature_2 : if !were_node_one { bs_node_sig } else { as_node_sig},
+                                       bitcoin_signature_1: if were_node_one { as_bitcoin_sig } else { bs_bitcoin_sig },
+                                       bitcoin_signature_2 : if !were_node_one { bs_bitcoin_sig } else { as_bitcoin_sig },
+                                       contents: $unsigned_msg
+                               }
+                       }
+               }
+
+               let unsigned_msg = dummy_unsigned_msg!();
+               sign_msg!(unsigned_msg);
+               assert_eq!(nodes[0].router.handle_channel_announcement(&chan_announcement).unwrap(), true);
+               let _ = nodes[0].router.handle_htlc_fail_channel_update(&msgs::HTLCFailChannelUpdate::ChannelClosed { short_channel_id : as_chan.get_short_channel_id().unwrap() } );
+
+               // Configured with Network::Testnet
+               let mut unsigned_msg = dummy_unsigned_msg!();
+               unsigned_msg.chain_hash = genesis_block(Network::Bitcoin).header.bitcoin_hash();
+               sign_msg!(unsigned_msg);
+               assert!(nodes[0].router.handle_channel_announcement(&chan_announcement).is_err());
+
+               let mut unsigned_msg = dummy_unsigned_msg!();
+               unsigned_msg.chain_hash = Sha256dHash::from_data(&[1,2,3,4,5,6,7,8,9]);
+               sign_msg!(unsigned_msg);
+               assert!(nodes[0].router.handle_channel_announcement(&chan_announcement).is_err());
+       }
 }
index e7f689e5fb85749dabcf25f5370940cb59b0f93f..e3697147f0a6e0f1d34657d9024ef10b19a4608d 100644 (file)
@@ -222,7 +222,7 @@ impl RoutingMessageHandler for Router {
                                //to the new HTLC max field in channel_update
                        },
                        Err(ChainError::NotSupported) => {
-                               // Tenatively accept, potentially exposing us to DoS attacks
+                               // Tentatively accept, potentially exposing us to DoS attacks
                        },
                        Err(ChainError::NotWatched) => {
                                return Err(HandleError{err: "Channel announced on an unknown chain", action: Some(ErrorAction::IgnoreError)});