X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fpeer_handler.rs;h=4809cecc4ad7cb008bf7b69bf9cf2723109c781d;hb=ebb55ff2aae55146239ff8fecd79c02ea4c3580f;hp=8094f256195d2fa5e1dd5c20c1f44ef3c3489570;hpb=88fef649b15fa030cb91de76d58346a0bc408834;p=rust-lightning diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 8094f256..4809cecc 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -8,27 +8,31 @@ use secp256k1::key::{SecretKey,PublicKey}; +use ln::features::InitFeatures; use ln::msgs; -use util::ser::{Writeable, Writer, Readable}; +use ln::msgs::ChannelMessageHandler; +use ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager}; +use util::ser::{Writeable, Readable, VecWriter}; use ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep}; use util::byte_utils; -use util::events::{MessageSendEvent}; +use util::events::{MessageSendEvent, MessageSendEventsProvider}; use util::logger::Logger; use std::collections::{HashMap,hash_map,HashSet,LinkedList}; use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::{cmp,error,hash,fmt}; +use std::ops::Deref; use bitcoin_hashes::sha256::Hash as Sha256; use bitcoin_hashes::sha256::HashEngine as Sha256Engine; use bitcoin_hashes::{HashEngine, Hash}; /// Provides references to trait impls which handle different types of messages. -pub struct MessageHandler { +pub struct MessageHandler where CM::Target: msgs::ChannelMessageHandler { /// A message handler which handles messages specific to channels. Usually this is just a /// ChannelManager object. - pub chan_handler: Arc, + pub chan_handler: CM, /// A message handler which handles messages updating our knowledge of the network channel /// graph. Usually this is just a Router object. pub route_handler: Arc, @@ -103,8 +107,7 @@ struct Peer { channel_encryptor: PeerChannelEncryptor, outbound: bool, their_node_id: Option, - their_global_features: Option, - their_local_features: Option, + their_features: Option, pending_outbound_buffer: LinkedList>, pending_outbound_buffer_first_msg_offset: usize, @@ -115,6 +118,8 @@ struct Peer { pending_read_is_header: bool, sync_status: InitSyncTracker, + + awaiting_pong: bool, } impl Peer { @@ -141,20 +146,6 @@ struct PeerHolder { /// Only add to this set when noise completes: node_id_to_descriptor: HashMap, } -struct MutPeerHolder<'a, Descriptor: SocketDescriptor + 'a> { - peers: &'a mut HashMap, - peers_needing_send: &'a mut HashSet, - node_id_to_descriptor: &'a mut HashMap, -} -impl PeerHolder { - fn borrow_parts(&mut self) -> MutPeerHolder { - MutPeerHolder { - peers: &mut self.peers, - peers_needing_send: &mut self.peers_needing_send, - node_id_to_descriptor: &mut self.node_id_to_descriptor, - } - } -} #[cfg(not(any(target_pointer_width = "32", target_pointer_width = "64")))] fn _check_usize_is_32_or_64() { @@ -162,10 +153,31 @@ fn _check_usize_is_32_or_64() { unsafe { mem::transmute::<*const usize, [u8; 4]>(panic!()); } } +/// SimpleArcPeerManager is useful when you need a PeerManager with a static lifetime, e.g. +/// when you're using lightning-net-tokio (since tokio::spawn requires parameters with static +/// lifetimes). Other times you can afford a reference, which is more efficient, in which case +/// SimpleRefPeerManager is the more appropriate type. Defining these type aliases prevents +/// issues such as overly long function definitions. +pub type SimpleArcPeerManager = 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 +/// need a PeerManager with a static lifetime. You'll need a static lifetime in cases such as +/// usage of lightning-net-tokio (since tokio::spawn requires parameters with static lifetimes). +/// But if this is not necessary, using a reference is more efficient. Defining these type aliases +/// helps with issues such as long function definitions. +pub type SimpleRefPeerManager<'a, SD, M> = PeerManager>; + /// A PeerManager manages a set of peers, described by their SocketDescriptor and marshalls socket /// events into messages which it passes on to its MessageHandlers. -pub struct PeerManager { - message_handler: MessageHandler, +/// +/// Rather than using a plain PeerManager, it is preferable to use either a SimpleArcPeerManager +/// a SimpleRefPeerManager, for conciseness. See their documentation for more details, but +/// essentially you should default to using a SimpleRefPeerManager, and use a +/// SimpleArcPeerManager when you require a PeerManager with a static lifetime, such as when +/// you're using lightning-net-tokio. +pub struct PeerManager where CM::Target: msgs::ChannelMessageHandler { + message_handler: MessageHandler, peers: Mutex>, our_node_secret: SecretKey, ephemeral_key_midstate: Sha256Engine, @@ -179,17 +191,6 @@ pub struct PeerManager { logger: Arc, } -struct VecWriter(Vec); -impl Writer for VecWriter { - fn write_all(&mut self, buf: &[u8]) -> Result<(), ::std::io::Error> { - self.0.extend_from_slice(buf); - Ok(()) - } - fn size_hint(&mut self, size: usize) { - self.0.reserve_exact(size); - } -} - macro_rules! encode_msg { ($msg: expr, $msg_code: expr) => {{ let mut msg = VecWriter(Vec::new()); @@ -204,11 +205,11 @@ const INITIAL_SYNCS_TO_SEND: usize = 5; /// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds. /// PeerIds may repeat, but only after disconnect_event() has been called. -impl PeerManager { +impl PeerManager where CM::Target: msgs::ChannelMessageHandler { /// Constructs a new PeerManager with the given message handlers and node_id secret key /// ephemeral_random_data is used to derive per-connection ephemeral keys and must be /// cryptographically secure random bytes. - pub fn new(message_handler: MessageHandler, our_node_secret: SecretKey, ephemeral_random_data: &[u8; 32], logger: Arc) -> PeerManager { + pub fn new(message_handler: MessageHandler, our_node_secret: SecretKey, ephemeral_random_data: &[u8; 32], logger: Arc) -> PeerManager { let mut ephemeral_key_midstate = Sha256::engine(); ephemeral_key_midstate.input(ephemeral_random_data); @@ -236,7 +237,7 @@ impl PeerManager { pub fn get_peer_node_ids(&self) -> Vec { let peers = self.peers.lock().unwrap(); peers.peers.values().filter_map(|p| { - if !p.channel_encryptor.is_ready_for_encryption() || p.their_global_features.is_none() { + if !p.channel_encryptor.is_ready_for_encryption() || p.their_features.is_none() { return None; } p.their_node_id @@ -274,8 +275,7 @@ impl PeerManager { channel_encryptor: peer_encryptor, outbound: true, their_node_id: None, - their_global_features: None, - their_local_features: None, + their_features: None, pending_outbound_buffer: LinkedList::new(), pending_outbound_buffer_first_msg_offset: 0, @@ -286,6 +286,8 @@ impl PeerManager { pending_read_is_header: false, sync_status: InitSyncTracker::NoSyncRequested, + + awaiting_pong: false, }).is_some() { panic!("PeerManager driver duplicated descriptors!"); }; @@ -310,8 +312,7 @@ impl PeerManager { channel_encryptor: peer_encryptor, outbound: false, their_node_id: None, - their_global_features: None, - their_local_features: None, + their_features: None, pending_outbound_buffer: LinkedList::new(), pending_outbound_buffer_first_msg_offset: 0, @@ -322,6 +323,8 @@ impl PeerManager { pending_read_is_header: false, sync_status: InitSyncTracker::NoSyncRequested, + + awaiting_pong: false, }).is_some() { panic!("PeerManager driver duplicated descriptors!"); }; @@ -447,7 +450,7 @@ impl PeerManager { fn do_read_event(&self, peer_descriptor: &mut Descriptor, data: Vec) -> Result { let pause_read = { let mut peers_lock = self.peers.lock().unwrap(); - let peers = peers_lock.borrow_parts(); + let peers = &mut *peers_lock; let pause_read = match peers.peers.get_mut(peer_descriptor) { None => panic!("Descriptor for read_event is not already known to PeerManager"), Some(peer) => { @@ -481,26 +484,21 @@ impl PeerManager { match $thing { Ok(x) => x, Err(e) => { - if let Some(action) = e.action { - match action { - msgs::ErrorAction::DisconnectPeer { msg: _ } => { - //TODO: Try to push msg - log_trace!(self, "Got Err handling message, disconnecting peer because {}", e.err); - return Err(PeerHandleError{ no_connection_possible: false }); - }, - msgs::ErrorAction::IgnoreError => { - log_trace!(self, "Got Err handling message, ignoring because {}", e.err); - continue; - }, - msgs::ErrorAction::SendErrorMessage { msg } => { - log_trace!(self, "Got Err handling message, sending Error message because {}", e.err); - encode_and_send_msg!(msg, 17); - continue; - }, - } - } else { - log_debug!(self, "Got Err handling message, action not yet filled in: {}", e.err); - return Err(PeerHandleError{ no_connection_possible: false }); + match e.action { + msgs::ErrorAction::DisconnectPeer { msg: _ } => { + //TODO: Try to push msg + log_trace!(self, "Got Err handling message, disconnecting peer because {}", e.err); + return Err(PeerHandleError{ no_connection_possible: false }); + }, + msgs::ErrorAction::IgnoreError => { + log_trace!(self, "Got Err handling message, ignoring because {}", e.err); + continue; + }, + msgs::ErrorAction::SendErrorMessage { msg } => { + log_trace!(self, "Got Err handling message, sending Error message because {}", e.err); + encode_and_send_msg!(msg, 17); + continue; + }, } } }; @@ -569,14 +567,13 @@ impl PeerManager { peer.their_node_id = Some(their_node_id); insert_node_id!(); - let mut local_features = msgs::LocalFeatures::new(); + let mut features = InitFeatures::supported(); if self.initial_syncs_sent.load(Ordering::Acquire) < INITIAL_SYNCS_TO_SEND { self.initial_syncs_sent.fetch_add(1, Ordering::AcqRel); - local_features.set_initial_routing_sync(); + features.set_initial_routing_sync(); } encode_and_send_msg!(msgs::Init { - global_features: msgs::GlobalFeatures::new(), - local_features, + features, }, 16); }, NextNoiseStep::ActThree => { @@ -605,7 +602,7 @@ impl PeerManager { let msg_type = byte_utils::slice_to_be16(&msg_data[0..2]); log_trace!(self, "Received message of type {} from {}", msg_type, log_pubkey!(peer.their_node_id.unwrap())); - if msg_type != 16 && peer.their_global_features.is_none() { + if msg_type != 16 && peer.their_features.is_none() { // Need an init message as first message log_trace!(self, "Peer {} sent non-Init first message", log_pubkey!(peer.their_node_id.unwrap())); return Err(PeerHandleError{ no_connection_possible: false }); @@ -615,46 +612,44 @@ impl PeerManager { // Connection control: 16 => { let msg = try_potential_decodeerror!(msgs::Init::read(&mut reader)); - if msg.global_features.requires_unknown_bits() { + if msg.features.requires_unknown_bits() { log_info!(self, "Peer global features required unknown version bits"); return Err(PeerHandleError{ no_connection_possible: true }); } - if msg.local_features.requires_unknown_bits() { + if msg.features.requires_unknown_bits() { log_info!(self, "Peer local features required unknown version bits"); return Err(PeerHandleError{ no_connection_possible: true }); } - if peer.their_global_features.is_some() { + if peer.their_features.is_some() { return Err(PeerHandleError{ no_connection_possible: false }); } log_info!(self, "Received peer Init message: data_loss_protect: {}, initial_routing_sync: {}, upfront_shutdown_script: {}, unkown local flags: {}, unknown global flags: {}", - if msg.local_features.supports_data_loss_protect() { "supported" } else { "not supported"}, - if msg.local_features.initial_routing_sync() { "requested" } else { "not requested" }, - if msg.local_features.supports_upfront_shutdown_script() { "supported" } else { "not supported"}, - if msg.local_features.supports_unknown_bits() { "present" } else { "none" }, - if msg.global_features.supports_unknown_bits() { "present" } else { "none" }); + if msg.features.supports_data_loss_protect() { "supported" } else { "not supported"}, + if msg.features.initial_routing_sync() { "requested" } else { "not requested" }, + if msg.features.supports_upfront_shutdown_script() { "supported" } else { "not supported"}, + if msg.features.supports_unknown_bits() { "present" } else { "none" }, + if msg.features.supports_unknown_bits() { "present" } else { "none" }); - if msg.local_features.initial_routing_sync() { + if msg.features.initial_routing_sync() { peer.sync_status = InitSyncTracker::ChannelsSyncing(0); peers.peers_needing_send.insert(peer_descriptor.clone()); } - peer.their_global_features = Some(msg.global_features); - peer.their_local_features = Some(msg.local_features); if !peer.outbound { - let mut local_features = msgs::LocalFeatures::new(); + let mut features = InitFeatures::supported(); if self.initial_syncs_sent.load(Ordering::Acquire) < INITIAL_SYNCS_TO_SEND { self.initial_syncs_sent.fetch_add(1, Ordering::AcqRel); - local_features.set_initial_routing_sync(); + features.set_initial_routing_sync(); } encode_and_send_msg!(msgs::Init { - global_features: msgs::GlobalFeatures::new(), - local_features, + features, }, 16); } - self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap()); + self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap(), &msg); + peer.their_features = Some(msg.features); }, 17 => { let msg = try_potential_decodeerror!(msgs::ErrorMessage::read(&mut reader)); @@ -685,79 +680,79 @@ impl PeerManager { } }, 19 => { + peer.awaiting_pong = false; try_potential_decodeerror!(msgs::Pong::read(&mut reader)); }, - // Channel control: 32 => { let msg = try_potential_decodeerror!(msgs::OpenChannel::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_local_features.clone().unwrap(), &msg)); + self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); }, 33 => { let msg = try_potential_decodeerror!(msgs::AcceptChannel::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_local_features.clone().unwrap(), &msg)); + self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_features.clone().unwrap(), &msg); }, 34 => { let msg = try_potential_decodeerror!(msgs::FundingCreated::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg); }, 35 => { let msg = try_potential_decodeerror!(msgs::FundingSigned::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_funding_signed(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_funding_signed(&peer.their_node_id.unwrap(), &msg); }, 36 => { let msg = try_potential_decodeerror!(msgs::FundingLocked::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg); }, 38 => { let msg = try_potential_decodeerror!(msgs::Shutdown::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg); }, 39 => { let msg = try_potential_decodeerror!(msgs::ClosingSigned::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg); }, 128 => { let msg = try_potential_decodeerror!(msgs::UpdateAddHTLC::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_update_add_htlc(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_update_add_htlc(&peer.their_node_id.unwrap(), &msg); }, 130 => { let msg = try_potential_decodeerror!(msgs::UpdateFulfillHTLC::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_update_fulfill_htlc(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_update_fulfill_htlc(&peer.their_node_id.unwrap(), &msg); }, 131 => { let msg = try_potential_decodeerror!(msgs::UpdateFailHTLC::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_update_fail_htlc(&peer.their_node_id.unwrap(), &msg); }, 135 => { let msg = try_potential_decodeerror!(msgs::UpdateFailMalformedHTLC::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_update_fail_malformed_htlc(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_update_fail_malformed_htlc(&peer.their_node_id.unwrap(), &msg); }, 132 => { let msg = try_potential_decodeerror!(msgs::CommitmentSigned::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg); }, 133 => { let msg = try_potential_decodeerror!(msgs::RevokeAndACK::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg); }, 134 => { let msg = try_potential_decodeerror!(msgs::UpdateFee::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_update_fee(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_update_fee(&peer.their_node_id.unwrap(), &msg); }, 136 => { let msg = try_potential_decodeerror!(msgs::ChannelReestablish::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg); }, // Routing control: 259 => { let msg = try_potential_decodeerror!(msgs::AnnouncementSignatures::read(&mut reader)); - try_potential_handleerror!(self.message_handler.chan_handler.handle_announcement_signatures(&peer.their_node_id.unwrap(), &msg)); + self.message_handler.chan_handler.handle_announcement_signatures(&peer.their_node_id.unwrap(), &msg); }, 256 => { let msg = try_potential_decodeerror!(msgs::ChannelAnnouncement::read(&mut reader)); @@ -818,7 +813,7 @@ impl PeerManager { let mut events_generated = self.message_handler.chan_handler.get_and_clear_pending_msg_events(); let mut peers_lock = self.peers.lock().unwrap(); - let peers = peers_lock.borrow_parts(); + let peers = &mut *peers_lock; for event in events_generated.drain(..) { macro_rules! get_peer_for_forwarding { ($node_id: expr, $handle_no_such_peer: block) => { @@ -832,7 +827,7 @@ impl PeerManager { }; match peers.peers.get_mut(&descriptor) { Some(peer) => { - if peer.their_global_features.is_none() { + if peer.their_features.is_none() { $handle_no_such_peer; continue; } @@ -983,7 +978,7 @@ impl PeerManager { let encoded_update_msg = encode_msg!(update_msg, 258); for (ref descriptor, ref mut peer) in peers.peers.iter_mut() { - if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_global_features.is_none() || + if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_features.is_none() || !peer.should_forward_channel(msg.contents.short_channel_id) { continue } @@ -1007,7 +1002,7 @@ impl PeerManager { let encoded_msg = encode_msg!(msg, 258); for (ref descriptor, ref mut peer) in peers.peers.iter_mut() { - if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_global_features.is_none() || + if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_features.is_none() || !peer.should_forward_channel(msg.contents.short_channel_id) { continue } @@ -1020,42 +1015,38 @@ impl PeerManager { self.message_handler.route_handler.handle_htlc_fail_channel_update(update); }, MessageSendEvent::HandleError { ref node_id, ref action } => { - if let Some(ref action) = *action { - match *action { - msgs::ErrorAction::DisconnectPeer { ref msg } => { - if let Some(mut descriptor) = peers.node_id_to_descriptor.remove(node_id) { - peers.peers_needing_send.remove(&descriptor); - if let Some(mut peer) = peers.peers.remove(&descriptor) { - if let Some(ref msg) = *msg { - log_trace!(self, "Handling DisconnectPeer HandleError event in peer_handler for node {} with message {}", - log_pubkey!(node_id), - msg.data); - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 17))); - // This isn't guaranteed to work, but if there is enough free - // room in the send buffer, put the error message there... - self.do_attempt_write_data(&mut descriptor, &mut peer); - } else { - log_trace!(self, "Handling DisconnectPeer HandleError event in peer_handler for node {} with no message", log_pubkey!(node_id)); - } + match *action { + msgs::ErrorAction::DisconnectPeer { ref msg } => { + if let Some(mut descriptor) = peers.node_id_to_descriptor.remove(node_id) { + peers.peers_needing_send.remove(&descriptor); + if let Some(mut peer) = peers.peers.remove(&descriptor) { + if let Some(ref msg) = *msg { + log_trace!(self, "Handling DisconnectPeer HandleError event in peer_handler for node {} with message {}", + log_pubkey!(node_id), + msg.data); + peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 17))); + // This isn't guaranteed to work, but if there is enough free + // room in the send buffer, put the error message there... + self.do_attempt_write_data(&mut descriptor, &mut peer); + } else { + log_trace!(self, "Handling DisconnectPeer HandleError event in peer_handler for node {} with no message", log_pubkey!(node_id)); } - descriptor.disconnect_socket(); - self.message_handler.chan_handler.peer_disconnected(&node_id, false); } - }, - msgs::ErrorAction::IgnoreError => {}, - msgs::ErrorAction::SendErrorMessage { ref msg } => { - log_trace!(self, "Handling SendErrorMessage HandleError event in peer_handler for node {} with message {}", - log_pubkey!(node_id), - msg.data); - let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, { - //TODO: Do whatever we're gonna do for handling dropped messages - }); - peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 17))); - self.do_attempt_write_data(&mut descriptor, peer); - }, - } - } else { - log_error!(self, "Got no-action HandleError Event in peer_handler for node {}, no such events should ever be generated!", log_pubkey!(node_id)); + descriptor.disconnect_socket(); + self.message_handler.chan_handler.peer_disconnected(&node_id, false); + } + }, + msgs::ErrorAction::IgnoreError => {}, + msgs::ErrorAction::SendErrorMessage { ref msg } => { + log_trace!(self, "Handling SendErrorMessage HandleError event in peer_handler for node {} with message {}", + log_pubkey!(node_id), + msg.data); + let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, { + //TODO: Do whatever we're gonna do for handling dropped messages + }); + peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 17))); + self.do_attempt_write_data(&mut descriptor, peer); + }, } } } @@ -1097,6 +1088,48 @@ impl PeerManager { } }; } + + /// This function should be called roughly once every 30 seconds. + /// It will send pings to each peer and disconnect those which did not respond to the last round of pings. + + /// Will most likely call send_data on all of the registered descriptors, thus, be very careful with reentrancy issues! + pub fn timer_tick_occured(&self) { + let mut peers_lock = self.peers.lock().unwrap(); + { + let peers = &mut *peers_lock; + let peers_needing_send = &mut peers.peers_needing_send; + let node_id_to_descriptor = &mut peers.node_id_to_descriptor; + let peers = &mut peers.peers; + + peers.retain(|descriptor, peer| { + if peer.awaiting_pong == true { + peers_needing_send.remove(descriptor); + match peer.their_node_id { + Some(node_id) => { + node_id_to_descriptor.remove(&node_id); + self.message_handler.chan_handler.peer_disconnected(&node_id, true); + }, + None => {} + } + } + + let ping = msgs::Ping { + ponglen: 0, + byteslen: 64, + }; + peer.pending_outbound_buffer.push_back(encode_msg!(ping, 18)); + let mut descriptor_clone = descriptor.clone(); + self.do_attempt_write_data(&mut descriptor_clone, peer); + + if peer.awaiting_pong { + false // Drop the peer + } else { + peer.awaiting_pong = true; + true + } + }); + } + } } #[cfg(test)] @@ -1127,22 +1160,31 @@ mod tests { fn disconnect_socket(&mut self) {} } - fn create_network(peer_count: usize) -> Vec> { + fn create_chan_handlers(peer_count: usize) -> Vec { + let mut chan_handlers = Vec::new(); + for _ in 0..peer_count { + let chan_handler = test_utils::TestChannelMessageHandler::new(); + chan_handlers.push(chan_handler); + } + + chan_handlers + } + + fn create_network<'a>(peer_count: usize, chan_handlers: &'a Vec) -> Vec> { let mut peers = Vec::new(); let mut rng = thread_rng(); let logger : Arc = Arc::new(test_utils::TestLogger::new()); let mut ephemeral_bytes = [0; 32]; rng.fill_bytes(&mut ephemeral_bytes); - for _ in 0..peer_count { - let chan_handler = test_utils::TestChannelMessageHandler::new(); + for i in 0..peer_count { let router = test_utils::TestRoutingMessageHandler::new(); let node_id = { let mut key_slice = [0;32]; rng.fill_bytes(&mut key_slice); SecretKey::from_slice(&key_slice).unwrap() }; - let msg_handler = MessageHandler { chan_handler: Arc::new(chan_handler), route_handler: Arc::new(router) }; + let msg_handler = MessageHandler { chan_handler: &chan_handlers[i], route_handler: Arc::new(router) }; let peer = PeerManager::new(msg_handler, node_id, &ephemeral_bytes, Arc::clone(&logger)); peers.push(peer); } @@ -1150,7 +1192,7 @@ mod tests { peers } - fn establish_connection(peer_a: &PeerManager, peer_b: &PeerManager) { + fn establish_connection<'a>(peer_a: &PeerManager, peer_b: &PeerManager) { let secp_ctx = Secp256k1::new(); let their_id = PublicKey::from_secret_key(&secp_ctx, &peer_b.our_node_secret); let fd = FileDescriptor { fd: 1}; @@ -1162,22 +1204,39 @@ mod tests { fn test_disconnect_peer() { // Simple test which builds a network of PeerManager, connects and brings them to NoiseState::Finished and // push a DisconnectPeer event to remove the node flagged by id - let mut peers = create_network(2); + let chan_handlers = create_chan_handlers(2); + let chan_handler = test_utils::TestChannelMessageHandler::new(); + let mut peers = create_network(2, &chan_handlers); establish_connection(&peers[0], &peers[1]); assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1); let secp_ctx = Secp256k1::new(); let their_id = PublicKey::from_secret_key(&secp_ctx, &peers[1].our_node_secret); - let chan_handler = test_utils::TestChannelMessageHandler::new(); chan_handler.pending_events.lock().unwrap().push(events::MessageSendEvent::HandleError { node_id: their_id, - action: Some(msgs::ErrorAction::DisconnectPeer { msg: None }), + action: msgs::ErrorAction::DisconnectPeer { msg: None }, }); assert_eq!(chan_handler.pending_events.lock().unwrap().len(), 1); - peers[0].message_handler.chan_handler = Arc::new(chan_handler); + peers[0].message_handler.chan_handler = &chan_handler; peers[0].process_events(); assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 0); } + #[test] + fn test_timer_tick_occured(){ + // Create peers, a vector of two peer managers, perform initial set up and check that peers[0] has one Peer. + let chan_handlers = create_chan_handlers(2); + let peers = create_network(2, &chan_handlers); + establish_connection(&peers[0], &peers[1]); + assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1); + + // peers[0] awaiting_pong is set to true, but the Peer is still connected + peers[0].timer_tick_occured(); + assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1); + + // Since timer_tick_occured() is called again when awaiting_pong is true, all Peers are disconnected + peers[0].timer_tick_occured(); + assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 0); + } }