Skip to content

Commit 326076f

Browse files
committed
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.
1 parent 7de9f52 commit 326076f

File tree

2 files changed

+40
-10
lines changed

2 files changed

+40
-10
lines changed

lightning/src/ln/peer_handler.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -773,12 +773,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
773773
},
774774

775775
// Unknown messages:
776-
wire::Message::Unknown(msg_type) => {
776+
wire::Message::Unknown(msg_type) if msg_type.is_even() => {
777777
// Fail the channel if message is an even, unknown type as per BOLT #1.
778-
if (msg_type & 1) == 0 {
779-
return Err(PeerHandleError{ no_connection_possible: true });
780-
}
778+
return Err(PeerHandleError{ no_connection_possible: true });
781779
},
780+
wire::Message::Unknown(_) => {},
782781
}
783782
}
784783
}

lightning/src/ln/wire.rs

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,18 @@ pub enum Message {
4747
NodeAnnouncement(msgs::NodeAnnouncement),
4848
ChannelUpdate(msgs::ChannelUpdate),
4949
/// A message that could not be decoded because its type is unknown.
50-
Unknown(u16),
50+
Unknown(MessageType),
51+
}
52+
53+
/// A number identifying a message to determine how it is encoded on the wire.
54+
#[derive(Clone, Copy)]
55+
pub struct MessageType {
56+
number: u16,
5157
}
5258

5359
impl Message {
5460
/// Returns the type that was used to decode the message payload.
55-
pub fn type_id(&self) -> u16 {
61+
pub fn type_id(&self) -> MessageType {
5662
match self {
5763
&Message::Init(ref msg) => msg.type_id(),
5864
&Message::Error(ref msg) => msg.type_id(),
@@ -82,6 +88,19 @@ impl Message {
8288
}
8389
}
8490

91+
impl MessageType {
92+
/// Returns whether the message type is even, indicating both endpoints must support it.
93+
pub fn is_even(&self) -> bool {
94+
(self.number & 1) == 0
95+
}
96+
}
97+
98+
impl ::std::fmt::Display for MessageType {
99+
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
100+
write!(f, "{}", self.number)
101+
}
102+
}
103+
85104
/// Reads a message from the data buffer consisting of a 2-byte big-endian type and a
86105
/// variable-length payload conforming to the type.
87106
///
@@ -161,7 +180,7 @@ pub fn read<R: ::std::io::Read>(buffer: &mut R) -> Result<Message, msgs::DecodeE
161180
Ok(Message::ChannelUpdate(Readable::read(buffer)?))
162181
},
163182
_ => {
164-
Ok(Message::Unknown(message_type))
183+
Ok(Message::Unknown(MessageType { number: message_type }))
165184
},
166185
}
167186
}
@@ -189,8 +208,8 @@ pub trait Encode {
189208

190209
/// Returns the type identifying the message payload. Convenience method for accessing
191210
/// [`TYPE`](TYPE).
192-
fn type_id(&self) -> u16 {
193-
Self::TYPE
211+
fn type_id(&self) -> MessageType {
212+
MessageType { number: Self::TYPE }
194213
}
195214
}
196215

@@ -339,7 +358,7 @@ mod tests {
339358
let mut reader = ::std::io::Cursor::new(buffer);
340359
let message = read(&mut reader).unwrap();
341360
match message {
342-
Message::Unknown(::std::u16::MAX) => (),
361+
Message::Unknown(MessageType { number: ::std::u16::MAX }) => (),
343362
_ => panic!("Expected message type {}; found: {}", ::std::u16::MAX, message.type_id()),
344363
}
345364
}
@@ -372,4 +391,16 @@ mod tests {
372391
_ => panic!("Expected pong message; found message type: {}", decoded_message.type_id()),
373392
}
374393
}
394+
395+
#[test]
396+
fn is_even_message_type() {
397+
let message = Message::Unknown(MessageType { number: 42 });
398+
assert!(message.type_id().is_even());
399+
}
400+
401+
#[test]
402+
fn is_odd_message_type() {
403+
let message = Message::Unknown(MessageType { number: 43 });
404+
assert!(!message.type_id().is_even());
405+
}
375406
}

0 commit comments

Comments
 (0)