Allow node_announcement timestamps of 0 in accordance with BOLT 7
[rust-lightning] / lightning / src / ln / wire.rs
index 963eaeb54a7f22ce780f23c0e7d705ab69cc8fdd..dfd11fc7e571760fca83d1364f679e986dc04b60 100644 (file)
@@ -47,12 +47,16 @@ pub enum Message {
        NodeAnnouncement(msgs::NodeAnnouncement),
        ChannelUpdate(msgs::ChannelUpdate),
        /// A message that could not be decoded because its type is unknown.
-       Unknown(u16),
+       Unknown(MessageType),
 }
 
+/// A number identifying a message to determine how it is encoded on the wire.
+#[derive(Clone, Copy)]
+pub struct MessageType(u16);
+
 impl Message {
        /// Returns the type that was used to decode the message payload.
-       pub fn type_id(&self) -> u16 {
+       pub fn type_id(&self) -> MessageType {
                match self {
                        &Message::Init(ref msg) => msg.type_id(),
                        &Message::Error(ref msg) => msg.type_id(),
@@ -82,6 +86,19 @@ impl Message {
        }
 }
 
+impl MessageType {
+       /// Returns whether the message type is even, indicating both endpoints must support it.
+       pub fn is_even(&self) -> bool {
+               (self.0 & 1) == 0
+       }
+}
+
+impl ::std::fmt::Display for MessageType {
+       fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
+               write!(f, "{}", self.0)
+       }
+}
+
 /// Reads a message from the data buffer consisting of a 2-byte big-endian type and a
 /// variable-length payload conforming to the type.
 ///
@@ -89,7 +106,7 @@ impl Message {
 ///
 /// Returns an error if the message payload code not be decoded as the specified type.
 pub fn read<R: ::std::io::Read>(buffer: &mut R) -> Result<Message, msgs::DecodeError> {
-       let message_type = <u16 as Readable<R>>::read(buffer)?;
+       let message_type = <u16 as Readable>::read(buffer)?;
        match message_type {
                msgs::Init::TYPE => {
                        Ok(Message::Init(Readable::read(buffer)?))
@@ -161,7 +178,7 @@ pub fn read<R: ::std::io::Read>(buffer: &mut R) -> Result<Message, msgs::DecodeE
                        Ok(Message::ChannelUpdate(Readable::read(buffer)?))
                },
                _ => {
-                       Ok(Message::Unknown(message_type))
+                       Ok(Message::Unknown(MessageType(message_type)))
                },
        }
 }
@@ -189,8 +206,8 @@ pub trait Encode {
 
        /// Returns the type identifying the message payload. Convenience method for accessing
        /// [`TYPE`](TYPE).
-       fn type_id(&self) -> u16 {
-               Self::TYPE
+       fn type_id(&self) -> MessageType {
+               MessageType(Self::TYPE)
        }
 }
 
@@ -339,7 +356,7 @@ mod tests {
                let mut reader = ::std::io::Cursor::new(buffer);
                let message = read(&mut reader).unwrap();
                match message {
-                       Message::Unknown(::std::u16::MAX) => (),
+                       Message::Unknown(MessageType(::std::u16::MAX)) => (),
                        _ => panic!("Expected message type {}; found: {}", ::std::u16::MAX, message.type_id()),
                }
        }
@@ -372,4 +389,16 @@ mod tests {
                        _ => panic!("Expected pong message; found message type: {}", decoded_message.type_id()),
                }
        }
+
+       #[test]
+       fn is_even_message_type() {
+               let message = Message::Unknown(MessageType(42));
+               assert!(message.type_id().is_even());
+       }
+
+       #[test]
+       fn is_odd_message_type() {
+               let message = Message::Unknown(MessageType(43));
+               assert!(!message.type_id().is_even());
+       }
 }