From 326076f5e8dff4eeaba0e3efe97fd2ca916cd616 Mon Sep 17 00:00:00 2001 From: Jeffrey Czyz Date: Fri, 24 Jan 2020 06:43:58 -0800 Subject: [PATCH] Move message type parity logic to the wire module Create a MessageType abstraction and use it throughout the wire module's external interfaces. Include an is_even method for clients to determine how to handle unknown messages. --- lightning/src/ln/peer_handler.rs | 7 +++--- lightning/src/ln/wire.rs | 43 +++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs index 30e208155..e25e50c28 100644 --- a/lightning/src/ln/peer_handler.rs +++ b/lightning/src/ln/peer_handler.rs @@ -773,12 +773,11 @@ impl PeerManager where }, // Unknown messages: - wire::Message::Unknown(msg_type) => { + wire::Message::Unknown(msg_type) if msg_type.is_even() => { // Fail the channel if message is an even, unknown type as per BOLT #1. - if (msg_type & 1) == 0 { - return Err(PeerHandleError{ no_connection_possible: true }); - } + return Err(PeerHandleError{ no_connection_possible: true }); }, + wire::Message::Unknown(_) => {}, } } } diff --git a/lightning/src/ln/wire.rs b/lightning/src/ln/wire.rs index 963eaeb54..9dedf580f 100644 --- a/lightning/src/ln/wire.rs +++ b/lightning/src/ln/wire.rs @@ -47,12 +47,18 @@ 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 { + number: 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 +88,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.number & 1) == 0 + } +} + +impl ::std::fmt::Display for MessageType { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "{}", self.number) + } +} + /// Reads a message from the data buffer consisting of a 2-byte big-endian type and a /// variable-length payload conforming to the type. /// @@ -161,7 +180,7 @@ pub fn read(buffer: &mut R) -> Result { - Ok(Message::Unknown(message_type)) + Ok(Message::Unknown(MessageType { number: message_type })) }, } } @@ -189,8 +208,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 { number: Self::TYPE } } } @@ -339,7 +358,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 { number: ::std::u16::MAX }) => (), _ => panic!("Expected message type {}; found: {}", ::std::u16::MAX, message.type_id()), } } @@ -372,4 +391,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 { number: 42 }); + assert!(message.type_id().is_even()); + } + + #[test] + fn is_odd_message_type() { + let message = Message::Unknown(MessageType { number: 43 }); + assert!(!message.type_id().is_even()); + } } -- 2.39.5