X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=lightning%2Fsrc%2Fln%2Fwire.rs;h=0ee280b50e4e72ffc4290333a960a9a09853ae93;hb=5a42be07a094ba39b93d98653f90730ba4c96ca6;hp=15a218060e6ffc52b4843272c3d6fa64113408b2;hpb=eee94672bee93b7d41986272563bdc23a3c6c95a;p=rust-lightning diff --git a/lightning/src/ln/wire.rs b/lightning/src/ln/wire.rs index 15a21806..0ee280b5 100644 --- a/lightning/src/ln/wire.rs +++ b/lightning/src/ln/wire.rs @@ -1,27 +1,30 @@ +// This file is Copyright its original authors, visible in version control +// history. +// +// This file is licensed under the Apache License, Version 2.0 or the MIT license +// , at your option. +// You may not use this file except in accordance with one or both of these +// licenses. + //! Wire encoding/decoding for Lightning messages according to [BOLT #1]. //! -//! Messages known by this module can be read from the wire using [`read`]. -//! The [`Message`] enum returned by [`read`] wraps the decoded message or the message type (if +//! Messages known by this module can be read from the wire using [`read()`]. +//! The [`Message`] enum returned by [`read()`] wraps the decoded message or the message type (if //! unknown) to use with pattern matching. //! //! Messages implementing the [`Encode`] trait define a message type and can be sent over the wire -//! using [`write`]. +//! using [`write()`]. //! //! [BOLT #1]: https://github.com/lightningnetwork/lightning-rfc/blob/master/01-messaging.md -//! [`read`]: fn.read.html -//! [`write`]: fn.write.html -//! [`Encode`]: trait.Encode.html -//! [`Message`]: enum.Message.html use ln::msgs; use util::ser::{Readable, Writeable, Writer}; -/// A Lightning message returned by [`read`] when decoding bytes received over the wire. Each -/// variant contains a message from [`ln::msgs`] or otherwise the message type if unknown. -/// -/// [`read`]: fn.read.html -/// [`ln::msgs`]: ../msgs/index.html +/// A Lightning message returned by [`read()`] when decoding bytes received over the wire. Each +/// variant contains a message from [`msgs`] or otherwise the message type if unknown. #[allow(missing_docs)] +#[derive(Debug)] pub enum Message { Init(msgs::Init), Error(msgs::ErrorMessage), @@ -46,15 +49,21 @@ pub enum Message { ChannelAnnouncement(msgs::ChannelAnnouncement), NodeAnnouncement(msgs::NodeAnnouncement), ChannelUpdate(msgs::ChannelUpdate), + QueryShortChannelIds(msgs::QueryShortChannelIds), + ReplyShortChannelIdsEnd(msgs::ReplyShortChannelIdsEnd), + QueryChannelRange(msgs::QueryChannelRange), + ReplyChannelRange(msgs::ReplyChannelRange), + GossipTimestampFilter(msgs::GossipTimestampFilter), /// A message that could not be decoded because its type is unknown. Unknown(MessageType), } /// A number identifying a message to determine how it is encoded on the wire. -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub struct MessageType(u16); impl Message { + #[allow(dead_code)] // This method is only used in tests /// Returns the type that was used to decode the message payload. pub fn type_id(&self) -> MessageType { match self { @@ -81,6 +90,11 @@ impl Message { &Message::ChannelAnnouncement(ref msg) => msg.type_id(), &Message::NodeAnnouncement(ref msg) => msg.type_id(), &Message::ChannelUpdate(ref msg) => msg.type_id(), + &Message::QueryShortChannelIds(ref msg) => msg.type_id(), + &Message::ReplyShortChannelIdsEnd(ref msg) => msg.type_id(), + &Message::QueryChannelRange(ref msg) => msg.type_id(), + &Message::ReplyChannelRange(ref msg) => msg.type_id(), + &Message::GossipTimestampFilter(ref msg) => msg.type_id(), &Message::Unknown(type_id) => type_id, } } @@ -93,8 +107,8 @@ impl MessageType { } } -impl ::std::fmt::Display for MessageType { - fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { +impl ::core::fmt::Display for MessageType { + fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result { write!(f, "{}", self.0) } } @@ -177,6 +191,21 @@ pub fn read(buffer: &mut R) -> Result { Ok(Message::ChannelUpdate(Readable::read(buffer)?)) }, + msgs::QueryShortChannelIds::TYPE => { + Ok(Message::QueryShortChannelIds(Readable::read(buffer)?)) + }, + msgs::ReplyShortChannelIdsEnd::TYPE => { + Ok(Message::ReplyShortChannelIdsEnd(Readable::read(buffer)?)) + }, + msgs::QueryChannelRange::TYPE => { + Ok(Message::QueryChannelRange(Readable::read(buffer)?)) + }, + msgs::ReplyChannelRange::TYPE => { + Ok(Message::ReplyChannelRange(Readable::read(buffer)?)) + } + msgs::GossipTimestampFilter::TYPE => { + Ok(Message::GossipTimestampFilter(Readable::read(buffer)?)) + }, _ => { Ok(Message::Unknown(MessageType(message_type))) }, @@ -196,16 +225,13 @@ pub fn write(message: &M, buffer: &mut W) -> R /// Defines a type-identified encoding for sending messages over the wire. /// -/// Messages implementing this trait specify a type and must be [`Writeable`] to use with [`write`]. -/// -/// [`Writeable`]: ../../util/ser/trait.Writeable.html -/// [`write`]: fn.write.html +/// Messages implementing this trait specify a type and must be [`Writeable`] to use with [`write()`]. pub trait Encode { /// The type identifying the message payload. const TYPE: u16; /// Returns the type identifying the message payload. Convenience method for accessing - /// [`TYPE`](TYPE). + /// [`Self::TYPE`]. fn type_id(&self) -> MessageType { MessageType(Self::TYPE) } @@ -303,10 +329,31 @@ impl Encode for msgs::ChannelUpdate { const TYPE: u16 = 258; } +impl Encode for msgs::QueryShortChannelIds { + const TYPE: u16 = 261; +} + +impl Encode for msgs::ReplyShortChannelIdsEnd { + const TYPE: u16 = 262; +} + +impl Encode for msgs::QueryChannelRange { + const TYPE: u16 = 263; +} + +impl Encode for msgs::ReplyChannelRange { + const TYPE: u16 = 264; +} + +impl Encode for msgs::GossipTimestampFilter { + const TYPE: u16 = 265; +} + #[cfg(test)] mod tests { use super::*; - use util::byte_utils; + use prelude::*; + use core::convert::TryInto; // Big-endian wire encoding of Pong message (type = 19, byteslen = 2). const ENCODED_PONG: [u8; 6] = [0u8, 19u8, 0u8, 2u8, 0u8, 0u8]; @@ -352,12 +399,12 @@ mod tests { #[test] fn read_unknown_message() { - let buffer = &byte_utils::be16_to_array(::std::u16::MAX); + let buffer = &::core::u16::MAX.to_be_bytes(); let mut reader = ::std::io::Cursor::new(buffer); let message = read(&mut reader).unwrap(); match message { - Message::Unknown(MessageType(::std::u16::MAX)) => (), - _ => panic!("Expected message type {}; found: {}", ::std::u16::MAX, message.type_id()), + Message::Unknown(MessageType(::core::u16::MAX)) => (), + _ => panic!("Expected message type {}; found: {}", ::core::u16::MAX, message.type_id()), } } @@ -367,9 +414,9 @@ mod tests { let mut buffer = Vec::new(); assert!(write(&message, &mut buffer).is_ok()); - let type_length = ::std::mem::size_of::(); + let type_length = ::core::mem::size_of::(); let (type_bytes, payload_bytes) = buffer.split_at(type_length); - assert_eq!(byte_utils::slice_to_be16(type_bytes), msgs::Pong::TYPE); + assert_eq!(u16::from_be_bytes(type_bytes.try_into().unwrap()), msgs::Pong::TYPE); assert_eq!(payload_bytes, &ENCODED_PONG[type_length..]); } @@ -406,24 +453,25 @@ mod tests { fn read_lnd_init_msg() { // Taken from lnd v0.9.0-beta. let buffer = vec![0, 16, 0, 2, 34, 0, 0, 3, 2, 162, 161]; - check_init_msg(buffer); + check_init_msg(buffer, false); } #[test] fn read_clightning_init_msg() { // Taken from c-lightning v0.8.0. let buffer = vec![0, 16, 0, 2, 34, 0, 0, 3, 2, 170, 162, 1, 32, 6, 34, 110, 70, 17, 26, 11, 89, 202, 175, 18, 96, 67, 235, 91, 191, 40, 195, 79, 58, 94, 51, 42, 31, 199, 178, 183, 60, 241, 136, 145, 15]; - check_init_msg(buffer); + check_init_msg(buffer, true); } - fn check_init_msg(buffer: Vec) { + fn check_init_msg(buffer: Vec, expect_unknown: bool) { let mut reader = ::std::io::Cursor::new(buffer); let decoded_msg = read(&mut reader).unwrap(); match decoded_msg { Message::Init(msgs::Init { features }) => { assert!(features.supports_variable_length_onion()); assert!(features.supports_upfront_shutdown_script()); - assert!(features.supports_unknown_bits()); + assert!(features.supports_gossip_queries()); + assert_eq!(expect_unknown, features.supports_unknown_bits()); assert!(!features.requires_unknown_bits()); assert!(!features.initial_routing_sync()); }, @@ -441,7 +489,7 @@ mod tests { Message::NodeAnnouncement(msgs::NodeAnnouncement { contents: msgs::UnsignedNodeAnnouncement { features, ..}, ..}) => { assert!(features.supports_variable_length_onion()); assert!(features.supports_upfront_shutdown_script()); - assert!(features.supports_unknown_bits()); + assert!(features.supports_gossip_queries()); assert!(!features.requires_unknown_bits()); }, _ => panic!("Expected node announcement, found message type: {}", decoded_msg.type_id())