X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fpeer_handler.rs;h=03aeedcdac31453f4d76eabb0d3812bb01b81194;hb=cd8f1de394591c85a635060b861105db9d51716c;hp=81ef41cf789d05aff4f25f659e97f1716e324d5d;hpb=920d1458c40f9d57679a17090c9fc090b1001d7b;p=rust-lightning diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 81ef41cf..03aeedcd 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -12,13 +12,17 @@ use ln::msgs; use util::ser::{Writeable, Writer, Readable}; use ln::peer_channel_encryptor::{PeerChannelEncryptor,NextNoiseStep}; use util::byte_utils; -use util::events::{EventsProvider,Event}; +use util::events::{MessageSendEvent}; use util::logger::Logger; -use std::collections::{HashMap,hash_map,LinkedList}; +use std::collections::{HashMap,hash_map,HashSet,LinkedList}; use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicUsize, Ordering}; -use std::{cmp,error,mem,hash,fmt}; +use std::{cmp,error,hash,fmt}; + +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 { @@ -88,6 +92,12 @@ impl error::Error for PeerHandleError { } } +enum InitSyncTracker{ + NoSyncRequested, + ChannelsSyncing(u64), + NodesSyncing(PublicKey), +} + struct Peer { channel_encryptor: PeerChannelEncryptor, outbound: bool, @@ -102,33 +112,68 @@ struct Peer { pending_read_buffer: Vec, pending_read_buffer_pos: usize, pending_read_is_header: bool, + + sync_status: InitSyncTracker, +} + +impl Peer { + /// Returns true if the channel announcements/updates for the given channel should be + /// forwarded to this peer. + /// If we are sending our routing table to this peer and we have not yet sent channel + /// announcements/updates for the given channel_id then we will send it when we get to that + /// point and we shouldn't send it yet to avoid sending duplicate updates. If we've already + /// sent the old versions, we should send the update, and so return true here. + fn should_forward_channel(&self, channel_id: u64)->bool{ + match self.sync_status { + InitSyncTracker::NoSyncRequested => true, + InitSyncTracker::ChannelsSyncing(i) => i < channel_id, + InitSyncTracker::NodesSyncing(_) => true, + } + } } struct PeerHolder { peers: HashMap, + /// Added to by do_read_event for cases where we pushed a message onto the send buffer but + /// didn't call do_attempt_write_data to avoid reentrancy. Cleared in process_events() + peers_needing_send: HashSet, /// 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() { + // See below, less than 32 bit pointers may be unsafe here! + unsafe { mem::transmute::<*const usize, [u8; 4]>(panic!()); } +} + /// 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, peers: Mutex>, - pending_events: Mutex>, our_node_secret: SecretKey, + ephemeral_key_midstate: Sha256Engine, + + // Usize needs to be at least 32 bits to avoid overflowing both low and high. If usize is 64 + // bits we will never realistically count into high: + peer_counter_low: AtomicUsize, + peer_counter_high: AtomicUsize, + initial_syncs_sent: AtomicUsize, logger: Arc, } @@ -160,12 +205,23 @@ const INITIAL_SYNCS_TO_SEND: usize = 5; /// PeerIds may repeat, but only after disconnect_event() has been called. impl PeerManager { /// Constructs a new PeerManager with the given message handlers and node_id secret key - pub fn new(message_handler: MessageHandler, our_node_secret: SecretKey, logger: Arc) -> PeerManager { + /// 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 { + let mut ephemeral_key_midstate = Sha256::engine(); + ephemeral_key_midstate.input(ephemeral_random_data); + PeerManager { message_handler: message_handler, - peers: Mutex::new(PeerHolder { peers: HashMap::new(), node_id_to_descriptor: HashMap::new() }), - pending_events: Mutex::new(Vec::new()), + peers: Mutex::new(PeerHolder { + peers: HashMap::new(), + peers_needing_send: HashSet::new(), + node_id_to_descriptor: HashMap::new() + }), our_node_secret: our_node_secret, + ephemeral_key_midstate, + peer_counter_low: AtomicUsize::new(0), + peer_counter_high: AtomicUsize::new(0), initial_syncs_sent: AtomicUsize::new(0), logger, } @@ -186,16 +242,29 @@ impl PeerManager { }).collect() } + fn get_ephemeral_key(&self) -> SecretKey { + let mut ephemeral_hash = self.ephemeral_key_midstate.clone(); + let low = self.peer_counter_low.fetch_add(1, Ordering::AcqRel); + let high = if low == 0 { + self.peer_counter_high.fetch_add(1, Ordering::AcqRel) + } else { + self.peer_counter_high.load(Ordering::Acquire) + }; + ephemeral_hash.input(&byte_utils::le64_to_array(low as u64)); + ephemeral_hash.input(&byte_utils::le64_to_array(high as u64)); + SecretKey::from_slice(&Sha256::from_engine(ephemeral_hash).into_inner()).expect("You broke SHA-256!") + } + /// Indicates a new outbound connection has been established to a node with the given node_id. /// Note that if an Err is returned here you MUST NOT call disconnect_event for the new /// descriptor but must disconnect the connection immediately. /// - /// Returns some bytes to send to the remote node. + /// Returns a small number of bytes to send to the remote node (currently always 50). /// /// Panics if descriptor is duplicative with some other descriptor which has not yet has a /// disconnect_event. pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result, PeerHandleError> { - let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone()); + let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key()); let res = peer_encryptor.get_act_one().to_vec(); let pending_read_buffer = [0; 50].to_vec(); // Noise act two is 50 bytes @@ -203,7 +272,7 @@ impl PeerManager { if peers.peers.insert(descriptor, Peer { channel_encryptor: peer_encryptor, outbound: true, - their_node_id: Some(their_node_id), + their_node_id: None, their_global_features: None, their_local_features: None, @@ -214,6 +283,8 @@ impl PeerManager { pending_read_buffer: pending_read_buffer, pending_read_buffer_pos: 0, pending_read_is_header: false, + + sync_status: InitSyncTracker::NoSyncRequested, }).is_some() { panic!("PeerManager driver duplicated descriptors!"); }; @@ -248,21 +319,74 @@ impl PeerManager { pending_read_buffer: pending_read_buffer, pending_read_buffer_pos: 0, pending_read_is_header: false, + + sync_status: InitSyncTracker::NoSyncRequested, }).is_some() { panic!("PeerManager driver duplicated descriptors!"); }; Ok(()) } - fn do_attempt_write_data(descriptor: &mut Descriptor, peer: &mut Peer) { + fn do_attempt_write_data(&self, descriptor: &mut Descriptor, peer: &mut Peer) { + macro_rules! encode_and_send_msg { + ($msg: expr, $msg_code: expr) => { + { + log_trace!(self, "Encoding and sending sync update message of type {} to {}", $msg_code, log_pubkey!(peer.their_node_id.unwrap())); + peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!($msg, $msg_code)[..])); + } + } + } + const MSG_BUFF_SIZE: usize = 10; while !peer.awaiting_write_event { + if peer.pending_outbound_buffer.len() < MSG_BUFF_SIZE { + match peer.sync_status { + InitSyncTracker::NoSyncRequested => {}, + InitSyncTracker::ChannelsSyncing(c) if c < 0xffff_ffff_ffff_ffff => { + let steps = ((MSG_BUFF_SIZE - peer.pending_outbound_buffer.len() + 2) / 3) as u8; + let all_messages = self.message_handler.route_handler.get_next_channel_announcements(0, steps); + for &(ref announce, ref update_a, ref update_b) in all_messages.iter() { + encode_and_send_msg!(announce, 256); + encode_and_send_msg!(update_a, 258); + encode_and_send_msg!(update_b, 258); + peer.sync_status = InitSyncTracker::ChannelsSyncing(announce.contents.short_channel_id + 1); + } + if all_messages.is_empty() || all_messages.len() != steps as usize { + peer.sync_status = InitSyncTracker::ChannelsSyncing(0xffff_ffff_ffff_ffff); + } + }, + InitSyncTracker::ChannelsSyncing(c) if c == 0xffff_ffff_ffff_ffff => { + let steps = (MSG_BUFF_SIZE - peer.pending_outbound_buffer.len()) as u8; + let all_messages = self.message_handler.route_handler.get_next_node_announcements(None, steps); + for msg in all_messages.iter() { + encode_and_send_msg!(msg, 256); + peer.sync_status = InitSyncTracker::NodesSyncing(msg.contents.node_id); + } + if all_messages.is_empty() || all_messages.len() != steps as usize { + peer.sync_status = InitSyncTracker::NoSyncRequested; + } + }, + InitSyncTracker::ChannelsSyncing(_) => unreachable!(), + InitSyncTracker::NodesSyncing(key) => { + let steps = (MSG_BUFF_SIZE - peer.pending_outbound_buffer.len()) as u8; + let all_messages = self.message_handler.route_handler.get_next_node_announcements(Some(&key), steps); + for msg in all_messages.iter() { + encode_and_send_msg!(msg, 256); + peer.sync_status = InitSyncTracker::NodesSyncing(msg.contents.node_id); + } + if all_messages.is_empty() || all_messages.len() != steps as usize { + peer.sync_status = InitSyncTracker::NoSyncRequested; + } + }, + } + } + if { let next_buff = match peer.pending_outbound_buffer.front() { None => return, Some(buff) => buff, }; - let should_be_reading = peer.pending_outbound_buffer.len() < 10; + let should_be_reading = peer.pending_outbound_buffer.len() < MSG_BUFF_SIZE; let data_sent = descriptor.send_data(next_buff, peer.pending_outbound_buffer_first_msg_offset, should_be_reading); peer.pending_outbound_buffer_first_msg_offset += data_sent; if peer.pending_outbound_buffer_first_msg_offset == next_buff.len() { true } else { false } @@ -290,7 +414,7 @@ impl PeerManager { None => panic!("Descriptor for write_event is not already known to PeerManager"), Some(peer) => { peer.awaiting_write_event = false; - Self::do_attempt_write_data(descriptor, peer); + self.do_attempt_write_data(descriptor, peer); } }; Ok(()) @@ -300,16 +424,12 @@ impl PeerManager { /// /// May return an Err to indicate that the connection should be closed. /// - /// Will very likely call send_data on the descriptor passed in (or a descriptor handed into - /// new_*_connection) before returning. Thus, be very careful with reentrancy issues! The - /// invariants around calling write_event in case a write did not fully complete must still - /// hold. Note that this function will often call send_data on many peers before returning, not - /// just this peer! + /// Will *not* call back into send_data on any descriptors to avoid reentrancy complexity. + /// Thus, however, you almost certainly want to call process_events() after any read_event to + /// generate send_data calls to handle responses. /// /// If Ok(true) is returned, further read_events should not be triggered until a write_event on - /// this file descriptor has resume_read set (preventing DoS issues in the send buffer). Note - /// that this must be true even if a send_data call with resume_read=true was made during the - /// course of this function! + /// this file descriptor has resume_read set (preventing DoS issues in the send buffer). /// /// Panics if the descriptor was not previously registered in a new_*_connection event. pub fn read_event(&self, peer_descriptor: &mut Descriptor, data: Vec) -> Result { @@ -349,6 +469,7 @@ impl PeerManager { { log_trace!(self, "Encoding and sending message of type {} to {}", $msg_code, log_pubkey!(peer.their_node_id.unwrap())); peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!($msg, $msg_code)[..])); + peers.peers_needing_send.insert(peer_descriptor.clone()); } } } @@ -392,11 +513,17 @@ impl PeerManager { match e { msgs::DecodeError::UnknownVersion => return Err(PeerHandleError{ no_connection_possible: false }), msgs::DecodeError::UnknownRequiredFeature => { - log_debug!(self, "Got a channel/node announcement with an known required feature flag, you may want to udpate!"); + log_debug!(self, "Got a channel/node announcement with an known required feature flag, you may want to update!"); continue; }, - msgs::DecodeError::InvalidValue => return Err(PeerHandleError{ no_connection_possible: false }), - msgs::DecodeError::ShortRead => return Err(PeerHandleError{ no_connection_possible: false }), + msgs::DecodeError::InvalidValue => { + log_debug!(self, "Got an invalid value while deserializing message"); + return Err(PeerHandleError{ no_connection_possible: false }); + }, + msgs::DecodeError::ShortRead => { + log_debug!(self, "Deserialization failed due to shortness of message"); + return Err(PeerHandleError{ no_connection_possible: false }); + }, msgs::DecodeError::ExtraAddressesPerType => { log_debug!(self, "Error decoding message, ignoring due to lnd spec incompatibility. See https://github.com/lightningnetwork/lnd/issues/1407"); continue; @@ -413,10 +540,14 @@ impl PeerManager { () => { match peers.node_id_to_descriptor.entry(peer.their_node_id.unwrap()) { hash_map::Entry::Occupied(_) => { + log_trace!(self, "Got second connection with {}, closing", log_pubkey!(peer.their_node_id.unwrap())); peer.their_node_id = None; // Unset so that we don't generate a peer_disconnected event return Err(PeerHandleError{ no_connection_possible: false }) }, - hash_map::Entry::Vacant(entry) => entry.insert(peer_descriptor.clone()), + hash_map::Entry::Vacant(entry) => { + log_trace!(self, "Finished noise handshake for connection with {}", log_pubkey!(peer.their_node_id.unwrap())); + entry.insert(peer_descriptor.clone()) + }, }; } } @@ -424,16 +555,17 @@ impl PeerManager { let next_step = peer.channel_encryptor.get_noise_step(); match next_step { NextNoiseStep::ActOne => { - let act_two = try_potential_handleerror!(peer.channel_encryptor.process_act_one_with_key(&peer.pending_read_buffer[..], &self.our_node_secret)).to_vec(); + let act_two = try_potential_handleerror!(peer.channel_encryptor.process_act_one_with_keys(&peer.pending_read_buffer[..], &self.our_node_secret, self.get_ephemeral_key())).to_vec(); peer.pending_outbound_buffer.push_back(act_two); peer.pending_read_buffer = [0; 66].to_vec(); // act three is 66 bytes long }, NextNoiseStep::ActTwo => { - let act_three = try_potential_handleerror!(peer.channel_encryptor.process_act_two(&peer.pending_read_buffer[..], &self.our_node_secret)).to_vec(); - peer.pending_outbound_buffer.push_back(act_three); + let (act_three, their_node_id) = try_potential_handleerror!(peer.channel_encryptor.process_act_two(&peer.pending_read_buffer[..], &self.our_node_secret)); + peer.pending_outbound_buffer.push_back(act_three.to_vec()); peer.pending_read_buffer = [0; 18].to_vec(); // Message length header is 18 bytes peer.pending_read_is_header = true; + peer.their_node_id = Some(their_node_id); insert_node_id!(); let mut local_features = msgs::LocalFeatures::new(); if self.initial_syncs_sent.load(Ordering::Acquire) < INITIAL_SYNCS_TO_SEND { @@ -473,6 +605,7 @@ impl PeerManager { 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() { // 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 }); } let mut reader = ::std::io::Cursor::new(&msg_data[2..]); @@ -492,10 +625,6 @@ impl PeerManager { log_info!(self, "Peer local features required data_loss_protect"); return Err(PeerHandleError{ no_connection_possible: true }); } - if msg.local_features.requires_upfront_shutdown_script() { - log_info!(self, "Peer local features required upfront_shutdown_script"); - return Err(PeerHandleError{ no_connection_possible: true }); - } if peer.their_global_features.is_some() { return Err(PeerHandleError{ no_connection_possible: false }); } @@ -507,6 +636,10 @@ impl PeerManager { if msg.local_features.supports_unknown_bits() { "present" } else { "none" }, if msg.global_features.supports_unknown_bits() { "present" } else { "none" }); + if msg.local_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); @@ -516,15 +649,14 @@ impl PeerManager { self.initial_syncs_sent.fetch_add(1, Ordering::AcqRel); local_features.set_initial_routing_sync(); } + encode_and_send_msg!(msgs::Init { global_features: msgs::GlobalFeatures::new(), local_features, }, 16); } - for msg in self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap()) { - encode_and_send_msg!(msg, 136); - } + self.message_handler.chan_handler.peer_connected(&peer.their_node_id.unwrap()); }, 17 => { let msg = try_potential_decodeerror!(msgs::ErrorMessage::read(&mut reader)); @@ -561,18 +693,16 @@ impl PeerManager { // Channel control: 32 => { let msg = try_potential_decodeerror!(msgs::OpenChannel::read(&mut reader)); - let resp = try_potential_handleerror!(self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), &msg)); - encode_and_send_msg!(resp, 33); + try_potential_handleerror!(self.message_handler.chan_handler.handle_open_channel(&peer.their_node_id.unwrap(), peer.their_local_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(), &msg)); + try_potential_handleerror!(self.message_handler.chan_handler.handle_accept_channel(&peer.their_node_id.unwrap(), peer.their_local_features.clone().unwrap(), &msg)); }, 34 => { let msg = try_potential_decodeerror!(msgs::FundingCreated::read(&mut reader)); - let resp = try_potential_handleerror!(self.message_handler.chan_handler.handle_funding_created(&peer.their_node_id.unwrap(), &msg)); - encode_and_send_msg!(resp, 35); + try_potential_handleerror!(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)); @@ -580,29 +710,16 @@ impl PeerManager { }, 36 => { let msg = try_potential_decodeerror!(msgs::FundingLocked::read(&mut reader)); - let resp_option = try_potential_handleerror!(self.message_handler.chan_handler.handle_funding_locked(&peer.their_node_id.unwrap(), &msg)); - match resp_option { - Some(resp) => encode_and_send_msg!(resp, 259), - None => {}, - } + try_potential_handleerror!(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)); - let resp_options = try_potential_handleerror!(self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg)); - if let Some(resp) = resp_options.0 { - encode_and_send_msg!(resp, 38); - } - if let Some(resp) = resp_options.1 { - encode_and_send_msg!(resp, 39); - } + try_potential_handleerror!(self.message_handler.chan_handler.handle_shutdown(&peer.their_node_id.unwrap(), &msg)); }, 39 => { let msg = try_potential_decodeerror!(msgs::ClosingSigned::read(&mut reader)); - let resp_option = try_potential_handleerror!(self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg)); - if let Some(resp) = resp_option { - encode_and_send_msg!(resp, 39); - } + try_potential_handleerror!(self.message_handler.chan_handler.handle_closing_signed(&peer.their_node_id.unwrap(), &msg)); }, 128 => { @@ -624,33 +741,11 @@ impl PeerManager { 132 => { let msg = try_potential_decodeerror!(msgs::CommitmentSigned::read(&mut reader)); - let resps = try_potential_handleerror!(self.message_handler.chan_handler.handle_commitment_signed(&peer.their_node_id.unwrap(), &msg)); - encode_and_send_msg!(resps.0, 133); - if let Some(resp) = resps.1 { - encode_and_send_msg!(resp, 132); - } + try_potential_handleerror!(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)); - let resp_option = try_potential_handleerror!(self.message_handler.chan_handler.handle_revoke_and_ack(&peer.their_node_id.unwrap(), &msg)); - match resp_option { - Some(resps) => { - for resp in resps.update_add_htlcs { - encode_and_send_msg!(resp, 128); - } - for resp in resps.update_fulfill_htlcs { - encode_and_send_msg!(resp, 130); - } - for resp in resps.update_fail_htlcs { - encode_and_send_msg!(resp, 131); - } - if let Some(resp) = resps.update_fee { - encode_and_send_msg!(resp, 134); - } - encode_and_send_msg!(resps.commitment_signed, 132); - }, - None => {}, - } + try_potential_handleerror!(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)); @@ -658,31 +753,7 @@ impl PeerManager { }, 136 => { let msg = try_potential_decodeerror!(msgs::ChannelReestablish::read(&mut reader)); - let (funding_locked, revoke_and_ack, commitment_update) = try_potential_handleerror!(self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg)); - if let Some(lock_msg) = funding_locked { - encode_and_send_msg!(lock_msg, 36); - } - if let Some(revoke_msg) = revoke_and_ack { - encode_and_send_msg!(revoke_msg, 133); - } - match commitment_update { - Some(resps) => { - for resp in resps.update_add_htlcs { - encode_and_send_msg!(resp, 128); - } - for resp in resps.update_fulfill_htlcs { - encode_and_send_msg!(resp, 130); - } - for resp in resps.update_fail_htlcs { - encode_and_send_msg!(resp, 131); - } - if let Some(resp) = resps.update_fee { - encode_and_send_msg!(resp, 134); - } - encode_and_send_msg!(resps.commitment_signed, 132); - }, - None => {}, - } + try_potential_handleerror!(self.message_handler.chan_handler.handle_channel_reestablish(&peer.their_node_id.unwrap(), &msg)); }, // Routing control: @@ -726,7 +797,7 @@ impl PeerManager { } } - Self::do_attempt_write_data(peer_descriptor, peer); + self.do_attempt_write_data(peer_descriptor, peer); peer.pending_outbound_buffer.len() > 10 // pause_read } @@ -735,22 +806,21 @@ impl PeerManager { pause_read }; - self.process_events(); - Ok(pause_read) } - /// Checks for any events generated by our handlers and processes them. May be needed after eg - /// calls to ChannelManager::process_pending_htlc_forward. + /// Checks for any events generated by our handlers and processes them. Includes sending most + /// response messages as well as messages generated by calls to handler functions directly (eg + /// functions like ChannelManager::process_pending_htlc_forward or send_payment). pub fn process_events(&self) { - let mut upstream_events = Vec::new(); { // TODO: There are some DoS attacks here where you can flood someone's outbound send // buffer by doing things like announcing channels on another node. We should be willing to // drop optional-ish messages when send buffers get full! - let mut events_generated = self.message_handler.chan_handler.get_and_clear_pending_events(); - let mut peers = self.peers.lock().unwrap(); + 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(); for event in events_generated.drain(..) { macro_rules! get_peer_for_forwarding { ($node_id: expr, $handle_no_such_peer: block) => { @@ -776,14 +846,17 @@ impl PeerManager { } } match event { - Event::FundingGenerationReady {..} => { /* Hand upstream */ }, - Event::FundingBroadcastSafe {..} => { /* Hand upstream */ }, - Event::PaymentReceived {..} => { /* Hand upstream */ }, - Event::PaymentSent {..} => { /* Hand upstream */ }, - Event::PaymentFailed {..} => { /* Hand upstream */ }, - Event::PendingHTLCsForwardable {..} => { /* Hand upstream */ }, - - Event::SendOpenChannel { ref node_id, ref msg } => { + MessageSendEvent::SendAcceptChannel { ref node_id, ref msg } => { + log_trace!(self, "Handling SendAcceptChannel event in peer_handler for node {} for channel {}", + log_pubkey!(node_id), + log_bytes!(msg.temporary_channel_id)); + let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, { + //TODO: Drop the pending channel? (or just let it timeout, but that sucks) + }); + peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 33))); + self.do_attempt_write_data(&mut descriptor, peer); + }, + MessageSendEvent::SendOpenChannel { ref node_id, ref msg } => { log_trace!(self, "Handling SendOpenChannel event in peer_handler for node {} for channel {}", log_pubkey!(node_id), log_bytes!(msg.temporary_channel_id)); @@ -791,10 +864,9 @@ impl PeerManager { //TODO: Drop the pending channel? (or just let it timeout, but that sucks) }); peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 32))); - Self::do_attempt_write_data(&mut descriptor, peer); - continue; + self.do_attempt_write_data(&mut descriptor, peer); }, - Event::SendFundingCreated { ref node_id, ref msg } => { + MessageSendEvent::SendFundingCreated { ref node_id, ref msg } => { log_trace!(self, "Handling SendFundingCreated event in peer_handler for node {} for channel {} (which becomes {})", log_pubkey!(node_id), log_bytes!(msg.temporary_channel_id), @@ -804,26 +876,41 @@ impl PeerManager { //they should just throw away this funding transaction }); peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 34))); - Self::do_attempt_write_data(&mut descriptor, peer); - continue; + self.do_attempt_write_data(&mut descriptor, peer); }, - Event::SendFundingLocked { ref node_id, ref msg, ref announcement_sigs } => { - log_trace!(self, "Handling SendFundingLocked event in peer_handler for node {}{} for channel {}", + MessageSendEvent::SendFundingSigned { ref node_id, ref msg } => { + log_trace!(self, "Handling SendFundingSigned event in peer_handler for node {} for channel {}", + log_pubkey!(node_id), + log_bytes!(msg.channel_id)); + let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, { + //TODO: generate a DiscardFunding event indicating to the wallet that + //they should just throw away this funding transaction + }); + peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 35))); + self.do_attempt_write_data(&mut descriptor, peer); + }, + MessageSendEvent::SendFundingLocked { ref node_id, ref msg } => { + log_trace!(self, "Handling SendFundingLocked event in peer_handler for node {} for channel {}", log_pubkey!(node_id), - if announcement_sigs.is_some() { " with announcement sigs" } else { "" }, log_bytes!(msg.channel_id)); 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, 36))); - match announcement_sigs { - &Some(ref announce_msg) => peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(announce_msg, 259))), - &None => {}, - } - Self::do_attempt_write_data(&mut descriptor, peer); - continue; + self.do_attempt_write_data(&mut descriptor, peer); }, - Event::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => { + MessageSendEvent::SendAnnouncementSignatures { ref node_id, ref msg } => { + log_trace!(self, "Handling SendAnnouncementSignatures event in peer_handler for node {} for channel {})", + log_pubkey!(node_id), + log_bytes!(msg.channel_id)); + let (mut descriptor, peer) = get_peer_for_forwarding!(node_id, { + //TODO: generate a DiscardFunding event indicating to the wallet that + //they should just throw away this funding transaction + }); + peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 259))); + self.do_attempt_write_data(&mut descriptor, peer); + }, + MessageSendEvent::UpdateHTLCs { ref node_id, updates: msgs::CommitmentUpdate { ref update_add_htlcs, ref update_fulfill_htlcs, ref update_fail_htlcs, ref update_fail_malformed_htlcs, ref update_fee, ref commitment_signed } } => { log_trace!(self, "Handling UpdateHTLCs event in peer_handler for node {} with {} adds, {} fulfills, {} fails for channel {}", log_pubkey!(node_id), update_add_htlcs.len(), @@ -849,10 +936,29 @@ impl PeerManager { peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(msg, 134))); } peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encode_msg!(commitment_signed, 132))); - Self::do_attempt_write_data(&mut descriptor, peer); - continue; + self.do_attempt_write_data(&mut descriptor, peer); + }, + MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => { + log_trace!(self, "Handling SendRevokeAndACK event in peer_handler for node {} for channel {}", + log_pubkey!(node_id), + log_bytes!(msg.channel_id)); + 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, 133))); + self.do_attempt_write_data(&mut descriptor, peer); + }, + MessageSendEvent::SendClosingSigned { ref node_id, ref msg } => { + log_trace!(self, "Handling SendClosingSigned event in peer_handler for node {} for channel {}", + log_pubkey!(node_id), + log_bytes!(msg.channel_id)); + 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, 39))); + self.do_attempt_write_data(&mut descriptor, peer); }, - Event::SendShutdown { ref node_id, ref msg } => { + MessageSendEvent::SendShutdown { ref node_id, ref msg } => { log_trace!(self, "Handling Shutdown event in peer_handler for node {} for channel {}", log_pubkey!(node_id), log_bytes!(msg.channel_id)); @@ -860,17 +966,27 @@ impl PeerManager { //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, 38))); - Self::do_attempt_write_data(&mut descriptor, peer); - continue; + self.do_attempt_write_data(&mut descriptor, peer); }, - Event::BroadcastChannelAnnouncement { ref msg, ref update_msg } => { + MessageSendEvent::SendChannelReestablish { ref node_id, ref msg } => { + log_trace!(self, "Handling SendChannelReestablish event in peer_handler for node {} for channel {}", + log_pubkey!(node_id), + log_bytes!(msg.channel_id)); + 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, 136))); + self.do_attempt_write_data(&mut descriptor, peer); + }, + MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => { log_trace!(self, "Handling BroadcastChannelAnnouncement event in peer_handler for short channel id {}", msg.contents.short_channel_id); if self.message_handler.route_handler.handle_channel_announcement(msg).is_ok() && self.message_handler.route_handler.handle_channel_update(update_msg).is_ok() { let encoded_msg = encode_msg!(msg, 256); 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_global_features.is_none() || + !peer.should_forward_channel(msg.contents.short_channel_id) { continue } match peer.their_node_id { @@ -883,35 +999,34 @@ impl PeerManager { } peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_msg[..])); peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_update_msg[..])); - Self::do_attempt_write_data(&mut (*descriptor).clone(), peer); + self.do_attempt_write_data(&mut (*descriptor).clone(), peer); } } - continue; }, - Event::BroadcastChannelUpdate { ref msg } => { + MessageSendEvent::BroadcastChannelUpdate { ref msg } => { log_trace!(self, "Handling BroadcastChannelUpdate event in peer_handler for short channel id {}", msg.contents.short_channel_id); if self.message_handler.route_handler.handle_channel_update(msg).is_ok() { 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_global_features.is_none() || + !peer.should_forward_channel(msg.contents.short_channel_id) { continue } peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_msg[..])); - Self::do_attempt_write_data(&mut (*descriptor).clone(), peer); + self.do_attempt_write_data(&mut (*descriptor).clone(), peer); } } - continue; }, - Event::PaymentFailureNetworkUpdate { ref update } => { + MessageSendEvent::PaymentFailureNetworkUpdate { ref update } => { self.message_handler.route_handler.handle_htlc_fail_channel_update(update); - continue; }, - Event::HandleError { ref node_id, ref action } => { + 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 {}", @@ -920,7 +1035,7 @@ impl PeerManager { 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); + 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)); } @@ -929,9 +1044,7 @@ impl PeerManager { self.message_handler.chan_handler.peer_disconnected(&node_id, false); } }, - msgs::ErrorAction::IgnoreError => { - continue; - }, + 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), @@ -940,23 +1053,22 @@ impl PeerManager { //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); + 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)); } - continue; } } - - upstream_events.push(event); } - } - let mut pending_events = self.pending_events.lock().unwrap(); - for event in upstream_events.drain(..) { - pending_events.push(event); + for mut descriptor in peers.peers_needing_send.drain() { + match peers.peers.get_mut(&descriptor) { + Some(peer) => self.do_attempt_write_data(&mut descriptor, peer), + None => panic!("Inconsistent peers set state!"), + } + } } } @@ -972,6 +1084,7 @@ impl PeerManager { fn disconnect_event_internal(&self, descriptor: &Descriptor, no_connection_possible: bool) { let mut peers = self.peers.lock().unwrap(); + peers.peers_needing_send.remove(descriptor); let peer_option = peers.peers.remove(descriptor); match peer_option { None => panic!("Descriptor for disconnect_event is not already known to PeerManager"), @@ -988,15 +1101,6 @@ impl PeerManager { } } -impl EventsProvider for PeerManager { - fn get_and_clear_pending_events(&self) -> Vec { - let mut pending_events = self.pending_events.lock().unwrap(); - let mut ret = Vec::new(); - mem::swap(&mut ret, &mut *pending_events); - ret - } -} - #[cfg(test)] mod tests { use ln::peer_handler::{PeerManager, MessageHandler, SocketDescriptor}; @@ -1027,10 +1131,11 @@ mod tests { } fn create_network(peer_count: usize) -> Vec> { - let secp_ctx = Secp256k1::new(); 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(); @@ -1038,10 +1143,10 @@ mod tests { let node_id = { let mut key_slice = [0;32]; rng.fill_bytes(&mut key_slice); - SecretKey::from_slice(&secp_ctx, &key_slice).unwrap() + SecretKey::from_slice(&key_slice).unwrap() }; let msg_handler = MessageHandler { chan_handler: Arc::new(chan_handler), route_handler: Arc::new(router) }; - let peer = PeerManager::new(msg_handler, node_id, Arc::clone(&logger)); + let peer = PeerManager::new(msg_handler, node_id, &ephemeral_bytes, Arc::clone(&logger)); peers.push(peer); } @@ -1059,7 +1164,7 @@ mod tests { #[test] fn test_disconnect_peer() { // Simple test which builds a network of PeerManager, connects and brings them to NoiseState::Finished and - // push an DisconnectPeer event to remove the node flagged by id + // push a DisconnectPeer event to remove the node flagged by id let mut peers = create_network(2); establish_connection(&peers[0], &peers[1]); assert_eq!(peers[0].peers.lock().unwrap().peers.len(), 1); @@ -1068,7 +1173,7 @@ mod tests { 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::Event::HandleError { + chan_handler.pending_events.lock().unwrap().push(events::MessageSendEvent::HandleError { node_id: their_id, action: Some(msgs::ErrorAction::DisconnectPeer { msg: None }), });