X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fpeer_handler.rs;fp=lightning%2Fsrc%2Fln%2Fpeer_handler.rs;h=9d3b7aca807688b6ce8caf8d900702ccfee9a8e0;hb=989cb064b5279da3c9e0f3a121637d8bbed81bfb;hp=4cf319a658dd9990e6eba055e1055203a610f962;hpb=6b0afbe4d46e2bf71ce8c54a05ab1beb7d38e36d;p=rust-lightning diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 4cf319a6..9d3b7aca 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -17,7 +17,7 @@ use bitcoin::secp256k1::{self, Secp256k1, SecretKey, PublicKey}; -use ln::features::InitFeatures; +use ln::features::{InitFeatures, NodeFeatures}; use ln::msgs; use ln::msgs::{ChannelMessageHandler, LightningError, NetAddress, OnionMessageHandler, RoutingMessageHandler}; use ln::channelmanager::{SimpleArcChannelManager, SimpleRefChannelManager}; @@ -27,6 +27,7 @@ use ln::wire; use ln::wire::Encode; use routing::gossip::{NetworkGraph, P2PGossipSync}; use util::atomic_counter::AtomicCounter; +use util::crypto::sign; use util::events::{MessageSendEvent, MessageSendEventsProvider, OnionMessageProvider}; use util::logger::Logger; @@ -34,13 +35,14 @@ use prelude::*; use io; use alloc::collections::LinkedList; use sync::{Arc, Mutex, MutexGuard, FairRwLock}; -use core::sync::atomic::{AtomicBool, Ordering}; +use core::sync::atomic::{AtomicBool, AtomicU64, Ordering}; use core::{cmp, hash, fmt, mem}; use core::ops::Deref; use core::convert::Infallible; #[cfg(feature = "std")] use std::error; use bitcoin::hashes::sha256::Hash as Sha256; +use bitcoin::hashes::sha256d::Hash as Sha256dHash; use bitcoin::hashes::sha256::HashEngine as Sha256Engine; use bitcoin::hashes::{HashEngine, Hash}; @@ -200,6 +202,7 @@ impl ChannelMessageHandler for ErroringMessageHandler { fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {} fn peer_connected(&self, _their_node_id: &PublicKey, _msg: &msgs::Init) {} fn handle_error(&self, _their_node_id: &PublicKey, _msg: &msgs::ErrorMessage) {} + fn provided_node_features(&self) -> NodeFeatures { NodeFeatures::empty() } } impl Deref for ErroringMessageHandler { type Target = ErroringMessageHandler; @@ -505,6 +508,11 @@ pub struct PeerManager PeerManager Self { + pub fn new_channel_only(channel_message_handler: CM, onion_message_handler: OM, our_node_secret: SecretKey, current_time: u64, ephemeral_random_data: &[u8; 32], logger: L) -> Self { Self::new(MessageHandler { chan_handler: channel_message_handler, route_handler: IgnoringMessageHandler{}, onion_message_handler, - }, our_node_secret, ephemeral_random_data, logger, IgnoringMessageHandler{}) + }, our_node_secret, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{}) } } @@ -569,16 +582,21 @@ impl PeerManager Self { + pub fn new_routing_only(routing_message_handler: RM, our_node_secret: SecretKey, current_time: u64, ephemeral_random_data: &[u8; 32], logger: L) -> Self { Self::new(MessageHandler { chan_handler: ErroringMessageHandler::new(), route_handler: routing_message_handler, onion_message_handler: IgnoringMessageHandler{}, - }, our_node_secret, ephemeral_random_data, logger, IgnoringMessageHandler{}) + }, our_node_secret, current_time, ephemeral_random_data, logger, IgnoringMessageHandler{}) } } @@ -632,7 +650,12 @@ impl, our_node_secret: SecretKey, ephemeral_random_data: &[u8; 32], logger: L, custom_message_handler: CMH) -> Self { + /// + /// `current_time` is used as an always-increasing counter that survives across restarts and is + /// incremented irregularly internally. In general it is best to simply use the current UNIX + /// timestamp, however if it is not available a persistent counter that increases once per + /// minute should suffice. + pub fn new(message_handler: MessageHandler, our_node_secret: SecretKey, current_time: u64, ephemeral_random_data: &[u8; 32], logger: L, custom_message_handler: CMH) -> Self { let mut ephemeral_key_midstate = Sha256::engine(); ephemeral_key_midstate.input(ephemeral_random_data); @@ -649,6 +672,7 @@ impl {}, } }, - MessageSendEvent::BroadcastNodeAnnouncement { msg } => { - log_debug!(self.logger, "Handling BroadcastNodeAnnouncement event in peer_handler"); - match self.message_handler.route_handler.handle_node_announcement(&msg) { - Ok(_) | Err(LightningError { action: msgs::ErrorAction::IgnoreDuplicateGossip, .. }) => - self.forward_broadcast_msg(peers, &wire::Message::NodeAnnouncement(msg), None), - _ => {}, - } - }, MessageSendEvent::BroadcastChannelUpdate { msg } => { log_debug!(self.logger, "Handling BroadcastChannelUpdate event in peer_handler for short channel id {}", msg.contents.short_channel_id); match self.message_handler.route_handler.handle_channel_update(&msg) { @@ -1906,6 +1922,63 @@ impl) { + if addresses.len() > 100 { + panic!("More than half the message size was taken up by public addresses!"); + } + + // While all existing nodes handle unsorted addresses just fine, the spec requires that + // addresses be sorted for future compatibility. + addresses.sort_by_key(|addr| addr.get_id()); + + let announcement = msgs::UnsignedNodeAnnouncement { + features: self.message_handler.chan_handler.provided_node_features(), + timestamp: self.last_node_announcement_serial.fetch_add(1, Ordering::AcqRel) as u32, + node_id: PublicKey::from_secret_key(&self.secp_ctx, &self.our_node_secret), + rgb, alias, addresses, + excess_address_data: Vec::new(), + excess_data: Vec::new(), + }; + let msghash = hash_to_message!(&Sha256dHash::hash(&announcement.encode()[..])[..]); + let node_announce_sig = sign(&self.secp_ctx, &msghash, &self.our_node_secret); + + let msg = msgs::NodeAnnouncement { + signature: node_announce_sig, + contents: announcement + }; + + log_debug!(self.logger, "Broadcasting NodeAnnouncement after passing it to our own RoutingMessageHandler."); + let _ = self.message_handler.route_handler.handle_node_announcement(&msg); + self.forward_broadcast_msg(&*self.peers.read().unwrap(), &wire::Message::NodeAnnouncement(msg), None); + } } fn is_gossip_msg(type_id: u16) -> bool { @@ -1989,7 +2062,7 @@ mod tests { let node_secret = SecretKey::from_slice(&[42 + i as u8; 32]).unwrap(); let ephemeral_bytes = [i as u8; 32]; let msg_handler = MessageHandler { chan_handler: &cfgs[i].chan_handler, route_handler: &cfgs[i].routing_handler, onion_message_handler: IgnoringMessageHandler {} }; - let peer = PeerManager::new(msg_handler, node_secret, &ephemeral_bytes, &cfgs[i].logger, IgnoringMessageHandler {}); + let peer = PeerManager::new(msg_handler, node_secret, 0, &ephemeral_bytes, &cfgs[i].logger, IgnoringMessageHandler {}); peers.push(peer); }