X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fpeer_handler.rs;h=1a39bbb3ae408e7047159e6d9f3f63267188b61f;hb=7cfafc98ba2429c6505ad11d9296e1ffe35cf60f;hp=a7f35a59c275baeb70ca6fdb607fe85283c4e965;hpb=32eb89474cdc1e400ef89eab76d590d19da4746a;p=rust-lightning diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index a7f35a59..1a39bbb3 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -15,6 +15,7 @@ //! call into the provided message handlers (probably a ChannelManager and P2PGossipSync) with //! messages they should handle, and encoding/sending response messages. +use bitcoin::blockdata::constants::ChainHash; use bitcoin::secp256k1::{self, Secp256k1, SecretKey, PublicKey}; use crate::sign::{KeysManager, NodeSigner, Recipient}; @@ -27,10 +28,11 @@ use crate::util::ser::{VecWriter, Writeable, Writer}; use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep}; use crate::ln::wire; use crate::ln::wire::{Encode, Type}; -use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger}; +use crate::onion_message::{CustomOnionMessageContents, CustomOnionMessageHandler, OffersMessage, OffersMessageHandler, SimpleArcOnionMessenger, SimpleRefOnionMessenger}; use crate::routing::gossip::{NetworkGraph, P2PGossipSync, NodeId, NodeAlias}; use crate::util::atomic_counter::AtomicCounter; use crate::util::logger::Logger; +use crate::util::string::PrintableString; use crate::prelude::*; use crate::io; @@ -116,9 +118,12 @@ impl OnionMessageHandler for IgnoringMessageHandler { InitFeatures::empty() } } +impl OffersMessageHandler for IgnoringMessageHandler { + fn handle_message(&self, _msg: OffersMessage) -> Option { None } +} impl CustomOnionMessageHandler for IgnoringMessageHandler { type CustomMessage = Infallible; - fn handle_custom_message(&self, _msg: Infallible) { + fn handle_custom_message(&self, _msg: Infallible) -> Option { // Since we always return `None` in the read the handle method should never be called. unreachable!(); } @@ -273,6 +278,13 @@ impl ChannelMessageHandler for ErroringMessageHandler { features } + fn get_genesis_hashes(&self) -> Option> { + // We don't enforce any chains upon peer connection for `ErroringMessageHandler` and leave it up + // to users of `ErroringMessageHandler` to make decisions on network compatiblility. + // There's not really any way to pull in specific networks here, and hardcoding can cause breakages. + None + } + fn handle_open_channel_v2(&self, their_node_id: &PublicKey, msg: &msgs::OpenChannelV2) { ErroringMessageHandler::push_error(self, their_node_id, msg.temporary_channel_id); } @@ -595,7 +607,15 @@ impl Peer { /// issues such as overly long function definitions. /// /// This is not exported to bindings users as `Arc`s don't make sense in bindings. -pub type SimpleArcPeerManager = PeerManager>, Arc>>, Arc, Arc>>, Arc>, Arc, IgnoringMessageHandler, Arc>; +pub type SimpleArcPeerManager = PeerManager< + SD, + Arc>, + Arc>>, Arc, Arc>>, + Arc>, + Arc, + IgnoringMessageHandler, + Arc +>; /// SimpleRefPeerManager is a type alias for a PeerManager reference, and is the reference /// counterpart to the SimpleArcPeerManager type alias. Use this type by default when you don't @@ -605,12 +625,25 @@ pub type SimpleArcPeerManager = PeerManager = PeerManager, &'f P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>, &'i SimpleRefOnionMessenger<'j, 'k, L>, &'f L, IgnoringMessageHandler, &'c KeysManager>; +pub type SimpleRefPeerManager< + 'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, 'j, 'k, 'l, 'm, 'n, SD, M, T, F, C, L +> = PeerManager< + SD, + &'n SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'm, M, T, F, L>, + &'f P2PGossipSync<&'g NetworkGraph<&'f L>, &'h C, &'f L>, + &'i SimpleRefOnionMessenger<'g, 'm, 'n, L>, + &'f L, + IgnoringMessageHandler, + &'c KeysManager +>; /// A generic trait which is implemented for all [`PeerManager`]s. This makes bounding functions or /// structs on any [`PeerManager`] much simpler as only this trait is needed as a bound, rather /// than the full set of bounds on [`PeerManager`] itself. +/// +/// This is not exported to bindings users as general cover traits aren't useful in other +/// languages. #[allow(missing_docs)] pub trait APeerManager { type Descriptor: SocketDescriptor; @@ -1333,7 +1366,8 @@ impl { - let mut data_is_printable = true; - for b in msg.data.bytes() { - if b < 32 || b > 126 { - data_is_printable = false; - break; - } - } - - if data_is_printable { - log_debug!(self.logger, "Got Err message from {}: {}", log_pubkey!(their_node_id), msg.data); - } else { - log_debug!(self.logger, "Got Err message from {} with non-ASCII error message", log_pubkey!(their_node_id)); - } + log_debug!(self.logger, "Got Err message from {}: {}", log_pubkey!(their_node_id), PrintableString(&msg.data)); self.message_handler.chan_handler.handle_error(&their_node_id, &msg); if msg.channel_id == [0; 32] { return Err(PeerHandleError { }.into()); } }, wire::Message::Warning(msg) => { - let mut data_is_printable = true; - for b in msg.data.bytes() { - if b < 32 || b > 126 { - data_is_printable = false; - break; - } - } - - if data_is_printable { - log_debug!(self.logger, "Got warning message from {}: {}", log_pubkey!(their_node_id), msg.data); - } else { - log_debug!(self.logger, "Got warning message from {} with non-ASCII error message", log_pubkey!(their_node_id)); - } + log_debug!(self.logger, "Got warning message from {}: {}", log_pubkey!(their_node_id), PrintableString(&msg.data)); }, wire::Message::Ping(msg) => { @@ -2459,6 +2489,8 @@ mod tests { use crate::ln::msgs::{LightningError, NetAddress}; use crate::util::test_utils; + use bitcoin::Network; + use bitcoin::blockdata::constants::ChainHash; use bitcoin::secp256k1::{PublicKey, SecretKey}; use crate::prelude::*; @@ -2537,7 +2569,7 @@ mod tests { }; cfgs.push( PeerManagerCfg{ - chan_handler: test_utils::TestChannelMessageHandler::new(), + chan_handler: test_utils::TestChannelMessageHandler::new(ChainHash::using_genesis_block(Network::Testnet)), logger: test_utils::TestLogger::new(), routing_handler: test_utils::TestRoutingMessageHandler::new(), custom_handler: TestCustomMessageHandler { features }, @@ -2549,7 +2581,7 @@ mod tests { cfgs } - fn create_incompatible_peermgr_cfgs(peer_count: usize) -> Vec { + fn create_feature_incompatible_peermgr_cfgs(peer_count: usize) -> Vec { let mut cfgs = Vec::new(); for i in 0..peer_count { let node_secret = SecretKey::from_slice(&[42 + i as u8; 32]).unwrap(); @@ -2560,7 +2592,27 @@ mod tests { }; cfgs.push( PeerManagerCfg{ - chan_handler: test_utils::TestChannelMessageHandler::new(), + chan_handler: test_utils::TestChannelMessageHandler::new(ChainHash::using_genesis_block(Network::Testnet)), + logger: test_utils::TestLogger::new(), + routing_handler: test_utils::TestRoutingMessageHandler::new(), + custom_handler: TestCustomMessageHandler { features }, + node_signer: test_utils::TestNodeSigner::new(node_secret), + } + ); + } + + cfgs + } + + fn create_chain_incompatible_peermgr_cfgs(peer_count: usize) -> Vec { + let mut cfgs = Vec::new(); + for i in 0..peer_count { + let node_secret = SecretKey::from_slice(&[42 + i as u8; 32]).unwrap(); + let features = InitFeatures::from_le_bytes(vec![0u8; 33]); + let network = ChainHash::from(&[i as u8; 32][..]); + cfgs.push( + PeerManagerCfg{ + chan_handler: test_utils::TestChannelMessageHandler::new(network), logger: test_utils::TestLogger::new(), routing_handler: test_utils::TestRoutingMessageHandler::new(), custom_handler: TestCustomMessageHandler { features }, @@ -2703,9 +2755,9 @@ mod tests { } #[test] - fn test_incompatible_peers() { + fn test_feature_incompatible_peers() { let cfgs = create_peermgr_cfgs(2); - let incompatible_cfgs = create_incompatible_peermgr_cfgs(2); + let incompatible_cfgs = create_feature_incompatible_peermgr_cfgs(2); let peers = create_network(2, &cfgs); let incompatible_peers = create_network(2, &incompatible_cfgs); @@ -2738,6 +2790,42 @@ mod tests { } } + #[test] + fn test_chain_incompatible_peers() { + let cfgs = create_peermgr_cfgs(2); + let incompatible_cfgs = create_chain_incompatible_peermgr_cfgs(2); + + let peers = create_network(2, &cfgs); + let incompatible_peers = create_network(2, &incompatible_cfgs); + let peer_pairs = [(&peers[0], &incompatible_peers[0]), (&incompatible_peers[1], &peers[1])]; + for (peer_a, peer_b) in peer_pairs.iter() { + let id_a = peer_a.node_signer.get_node_id(Recipient::Node).unwrap(); + let mut fd_a = FileDescriptor { + fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())), + disconnect: Arc::new(AtomicBool::new(false)), + }; + let addr_a = NetAddress::IPv4{addr: [127, 0, 0, 1], port: 1000}; + let mut fd_b = FileDescriptor { + fd: 1, outbound_data: Arc::new(Mutex::new(Vec::new())), + disconnect: Arc::new(AtomicBool::new(false)), + }; + let addr_b = NetAddress::IPv4{addr: [127, 0, 0, 1], port: 1001}; + let initial_data = peer_b.new_outbound_connection(id_a, fd_b.clone(), Some(addr_a.clone())).unwrap(); + peer_a.new_inbound_connection(fd_a.clone(), Some(addr_b.clone())).unwrap(); + assert_eq!(peer_a.read_event(&mut fd_a, &initial_data).unwrap(), false); + peer_a.process_events(); + + let a_data = fd_a.outbound_data.lock().unwrap().split_off(0); + assert_eq!(peer_b.read_event(&mut fd_b, &a_data).unwrap(), false); + + peer_b.process_events(); + let b_data = fd_b.outbound_data.lock().unwrap().split_off(0); + + // Should fail because of incompatible chains + assert!(peer_a.read_event(&mut fd_a, &b_data).is_err()); + } + } + #[test] fn test_disconnect_peer() { // Simple test which builds a network of PeerManager, connects and brings them to NoiseState::Finished and @@ -2762,8 +2850,8 @@ mod tests { // Simple test which builds a network of PeerManager, connects and brings them to NoiseState::Finished and // push a message from one peer to another. let cfgs = create_peermgr_cfgs(2); - let a_chan_handler = test_utils::TestChannelMessageHandler::new(); - let b_chan_handler = test_utils::TestChannelMessageHandler::new(); + let a_chan_handler = test_utils::TestChannelMessageHandler::new(ChainHash::using_genesis_block(Network::Testnet)); + let b_chan_handler = test_utils::TestChannelMessageHandler::new(ChainHash::using_genesis_block(Network::Testnet)); let mut peers = create_network(2, &cfgs); let (fd_a, mut fd_b) = establish_connection(&peers[0], &peers[1]); assert_eq!(peers[0].peers.read().unwrap().len(), 1);