X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fmsgs.rs;h=712158a97bc604a39ba173e714e8bbeafbfcd399;hb=d873e7278946e12ed591b23f1f4014adc09f5770;hp=9111a1ed657a544c9ca0709193e99c0069d967be;hpb=55e5aafcfe3b4d55df1fa500846e3a0f093f85c8;p=rust-lightning diff --git a/lightning/src/ln/msgs.rs b/lightning/src/ln/msgs.rs index 9111a1ed..712158a9 100644 --- a/lightning/src/ln/msgs.rs +++ b/lightning/src/ln/msgs.rs @@ -33,9 +33,10 @@ use bitcoin::hash_types::{Txid, BlockHash}; use ln::features::{ChannelFeatures, InitFeatures, NodeFeatures}; use std::{cmp, fmt}; +use std::fmt::Debug; use std::io::Read; -use util::events; +use util::events::MessageSendEventsProvider; use util::ser::{Readable, Writeable, Writer, FixedLengthReader, HighZeroBytesDroppedVarInt}; use ln::channelmanager::{PaymentPreimage, PaymentHash, PaymentSecret}; @@ -44,7 +45,7 @@ use ln::channelmanager::{PaymentPreimage, PaymentHash, PaymentSecret}; pub(crate) const MAX_VALUE_MSAT: u64 = 21_000_000_0000_0000_000; /// An error in decoding a message or struct. -#[derive(Debug)] +#[derive(Clone, Debug)] pub enum DecodeError { /// A version byte specified something we don't know how to handle. /// Includes unknown realm byte in an OnionHopData packet @@ -60,7 +61,7 @@ pub enum DecodeError { /// A length descriptor in the packet didn't describe the later data correctly BadLengthDescriptor, /// Error from std::io - Io(::std::io::Error), + Io(::std::io::ErrorKind), } /// An init message to be sent or received from a peer @@ -390,15 +391,6 @@ pub enum NetAddress { }, } impl NetAddress { - fn get_id(&self) -> u8 { - match self { - &NetAddress::IPv4 {..} => { 1 }, - &NetAddress::IPv6 {..} => { 2 }, - &NetAddress::OnionV2 {..} => { 3 }, - &NetAddress::OnionV3 {..} => { 4 }, - } - } - /// Strict byte-length of address descriptor, 1-byte type not recorded fn len(&self) -> u16 { match self { @@ -602,9 +594,8 @@ pub struct ReplyChannelRange { pub first_blocknum: u32, /// The number of blocks included in the range of the reply pub number_of_blocks: u32, - /// Indicates if the query recipient maintains up-to-date channel - /// information for the chain_hash - pub full_information: bool, + /// True when this is the final reply for a query + pub sync_complete: bool, /// The short_channel_ids in the channel range pub short_channel_ids: Vec, } @@ -675,6 +666,7 @@ pub enum ErrorAction { } /// An Err type for failure to process messages. +#[derive(Clone)] pub struct LightningError { /// A human-readable message describing the error pub err: String, @@ -746,7 +738,7 @@ pub enum OptionalField { /// /// Messages MAY be called in parallel when they originate from different their_node_ids, however /// they MUST NOT be called in parallel when the two calls have the same their_node_id. -pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Sync { +pub trait ChannelMessageHandler : MessageSendEventsProvider + Send + Sync { //Channel init: /// Handle an incoming open_channel message from the given peer. fn handle_open_channel(&self, their_node_id: &PublicKey, their_features: InitFeatures, msg: &OpenChannel); @@ -804,7 +796,13 @@ pub trait ChannelMessageHandler : events::MessageSendEventsProvider + Send + Syn } /// A trait to describe an object which can receive routing messages. -pub trait RoutingMessageHandler : Send + Sync + events::MessageSendEventsProvider { +/// +/// # Implementor DoS Warnings +/// +/// For `gossip_queries` messages there are potential DoS vectors when handling +/// inbound queries. Implementors using an on-disk network graph should be aware of +/// repeated disk I/O for queries accessing different parts of the network graph. +pub trait RoutingMessageHandler : Send + Sync + MessageSendEventsProvider { /// Handle an incoming node_announcement message, returning true if it should be forwarded on, /// false or returning an Err otherwise. fn handle_node_announcement(&self, msg: &NodeAnnouncement) -> Result; @@ -825,29 +823,25 @@ pub trait RoutingMessageHandler : Send + Sync + events::MessageSendEventsProvide /// immediately higher (as defined by ::cmp) than starting_point. /// If None is provided for starting_point, we start at the first node. fn get_next_node_announcements(&self, starting_point: Option<&PublicKey>, batch_amount: u8) -> Vec; - /// Returns whether a full sync should be requested from a peer. - fn should_request_full_sync(&self, node_id: &PublicKey) -> bool; - /// Queries a peer for a list of channels with a funding UTXO in the requested - /// chain and range of blocks. - fn query_channel_range(&self, their_node_id: &PublicKey, chain_hash: BlockHash, first_blocknum: u32, number_of_blocks: u32) -> Result<(), LightningError>; - /// Queries a peer for routing gossip messages for a set of channels identified - /// by their short_channel_ids. - fn query_short_channel_ids(&self, their_node_id: &PublicKey, chain_hash: BlockHash, short_channel_ids: Vec) -> Result<(), LightningError>; + /// Called when a connection is established with a peer. This can be used to + /// perform routing table synchronization using a strategy defined by the + /// implementor. + fn sync_routing_table(&self, their_node_id: &PublicKey, init: &Init); /// Handles the reply of a query we initiated to learn about channels /// for a given range of blocks. We can expect to receive one or more /// replies to a single query. - fn handle_reply_channel_range(&self, their_node_id: &PublicKey, msg: &ReplyChannelRange) -> Result<(), LightningError>; + fn handle_reply_channel_range(&self, their_node_id: &PublicKey, msg: ReplyChannelRange) -> Result<(), LightningError>; /// Handles the reply of a query we initiated asking for routing gossip /// messages for a list of channels. We should receive this message when /// a node has completed its best effort to send us the pertaining routing /// gossip messages. - fn handle_reply_short_channel_ids_end(&self, their_node_id: &PublicKey, msg: &ReplyShortChannelIdsEnd) -> Result<(), LightningError>; + fn handle_reply_short_channel_ids_end(&self, their_node_id: &PublicKey, msg: ReplyShortChannelIdsEnd) -> Result<(), LightningError>; /// Handles when a peer asks us to send a list of short_channel_ids /// for the requested range of blocks. - fn handle_query_channel_range(&self, their_node_id: &PublicKey, msg: &QueryChannelRange) -> Result<(), LightningError>; + fn handle_query_channel_range(&self, their_node_id: &PublicKey, msg: QueryChannelRange) -> Result<(), LightningError>; /// Handles when a peer asks us to send routing gossip messages for a /// list of short_channel_ids. - fn handle_query_short_channel_ids(&self, their_node_id: &PublicKey, msg: &QueryShortChannelIds) -> Result<(), LightningError>; + fn handle_query_short_channel_ids(&self, their_node_id: &PublicKey, msg: QueryShortChannelIds) -> Result<(), LightningError>; } mod fuzzy_internal_msgs { @@ -948,7 +942,7 @@ impl From<::std::io::Error> for DecodeError { if e.kind() == ::std::io::ErrorKind::UnexpectedEof { DecodeError::ShortRead } else { - DecodeError::Io(e) + DecodeError::Io(e.kind()) } } } @@ -1532,14 +1526,12 @@ impl Writeable for UnsignedNodeAnnouncement { w.write_all(&self.rgb)?; self.alias.write(w)?; - let mut addrs_to_encode = self.addresses.clone(); - addrs_to_encode.sort_by(|a, b| { a.get_id().cmp(&b.get_id()) }); let mut addr_len = 0; - for addr in &addrs_to_encode { + for addr in self.addresses.iter() { addr_len += 1 + addr.len(); } (addr_len + self.excess_address_data.len() as u16).write(w)?; - for addr in addrs_to_encode { + for addr in self.addresses.iter() { addr.write(w)?; } w.write_all(&self.excess_address_data[..])?; @@ -1559,7 +1551,6 @@ impl Readable for UnsignedNodeAnnouncement { let addr_len: u16 = Readable::read(r)?; let mut addresses: Vec = Vec::new(); - let mut highest_addr_type = 0; let mut addr_readpos = 0; let mut excess = false; let mut excess_byte = 0; @@ -1567,11 +1558,6 @@ impl Readable for UnsignedNodeAnnouncement { if addr_len <= addr_readpos { break; } match Readable::read(r) { Ok(Ok(addr)) => { - if addr.get_id() < highest_addr_type { - // Addresses must be sorted in increasing order - return Err(DecodeError::InvalidValue); - } - highest_addr_type = addr.get_id(); if addr_len < addr_readpos + 1 + addr.len() { return Err(DecodeError::BadLengthDescriptor); } @@ -1725,7 +1711,7 @@ impl Readable for ReplyChannelRange { let chain_hash: BlockHash = Readable::read(r)?; let first_blocknum: u32 = Readable::read(r)?; let number_of_blocks: u32 = Readable::read(r)?; - let full_information: bool = Readable::read(r)?; + let sync_complete: bool = Readable::read(r)?; // We expect the encoding_len to always includes the 1-byte // encoding_type and that short_channel_ids are 8-bytes each @@ -1753,7 +1739,7 @@ impl Readable for ReplyChannelRange { chain_hash, first_blocknum, number_of_blocks, - full_information, + sync_complete, short_channel_ids }) } @@ -1766,7 +1752,7 @@ impl Writeable for ReplyChannelRange { self.chain_hash.write(w)?; self.first_blocknum.write(w)?; self.number_of_blocks.write(w)?; - self.full_information.write(w)?; + self.sync_complete.write(w)?; encoding_len.write(w)?; (EncodingType::Uncompressed as u8).write(w)?; @@ -2567,7 +2553,7 @@ mod tests { chain_hash: expected_chain_hash, first_blocknum: 756230, number_of_blocks: 1500, - full_information: true, + sync_complete: true, short_channel_ids: vec![0x000000000000008e, 0x0000000000003c69, 0x000000000045a6c4], }; @@ -2580,7 +2566,7 @@ mod tests { assert_eq!(reply_channel_range.chain_hash, expected_chain_hash); assert_eq!(reply_channel_range.first_blocknum, 756230); assert_eq!(reply_channel_range.number_of_blocks, 1500); - assert_eq!(reply_channel_range.full_information, true); + assert_eq!(reply_channel_range.sync_complete, true); assert_eq!(reply_channel_range.short_channel_ids[0], 0x000000000000008e); assert_eq!(reply_channel_range.short_channel_ids[1], 0x0000000000003c69); assert_eq!(reply_channel_range.short_channel_ids[2], 0x000000000045a6c4);