Drop `wire::write` and replace `encode_msg!` macro
What changed, and why it matters
This is a routine internal code cleanup in the Lightning Dev Kit's message serialization layer. It removes an old helper function (`wire::write`) and a macro (`encode_msg!`), replacing them with direct calls to `Message::write`/`Type::write`. The change does not alter the wire format or add any new behavior; it is purely a refactoring to simplify the code.
No security action required. Treat as normal code-review/merge for a refactoring change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors message encoding in rust-lightning. It deletes the wire::write function and the encode_msg! macro, replacing them with an encode_message<T: wire::Type> function that takes a wire::Message<T>, writes the 2-byte type prefix, then writes the payload. Call sites in peer_channel_encryptor.rs and peer_handler.rs are updated to use the new function, and several gossip forwarding paths are converted from borrowed references to move semantics. The wire encoding format remains identical, and the removed unit tests only verified the deleted helper, not protocol behavior.
Changed components
lightning/src/ln/wire.rslightning/src/ln/peer_handler.rslightning/src/ln/peer_channel_encryptor.rsInspect captured patch +39 / −72
diff --git a/lightning/src/ln/peer_channel_encryptor.rs b/lightning/src/ln/peer_channel_encryptor.rs
index 1d34d9a..894de04 100644
--- a/lightning/src/ln/peer_channel_encryptor.rs
+++ b/lightning/src/ln/peer_channel_encryptor.rs
@@ -12,7 +12,9 @@ use crate::prelude::*;
use crate::ln::msgs;
use crate::ln::msgs::LightningError;
use crate::ln::wire;
+use crate::ln::wire::Type;
use crate::sign::{NodeSigner, Recipient};
+use crate::util::ser::Writeable;
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash, HashEngine};
@@ -570,7 +572,9 @@ impl PeerChannelEncryptor {
// for the 2-byte message type prefix and its MAC.
let mut res = VecWriter(Vec::with_capacity(MSG_BUF_ALLOC_SIZE));
res.0.resize(16 + 2, 0);
- wire::write(&message, &mut res).expect("In-memory messages must never fail to serialize");
+
+ message.type_id().write(&mut res).expect("In-memory messages must never fail to serialize");
+ message.write(&mut res).expect("In-memory messages must never fail to serialize");
self.encrypt_message_with_header_0s(&mut res.0);
res.0
diff --git a/lightning/src/ln/peer_handler.rs b/lightning/src/ln/peer_handler.rs
index 8a6c6a7..4d1dff9 100644
--- a/lightning/src/ln/peer_handler.rs
+++ b/lightning/src/ln/peer_handler.rs
@@ -1144,12 +1144,11 @@ impl From<LightningError> for MessageHandlingError {
}
}
-macro_rules! encode_msg {
- ($msg: expr) => {{
- let mut buffer = VecWriter(Vec::with_capacity(MSG_BUF_ALLOC_SIZE));
- wire::write($msg, &mut buffer).unwrap();
- buffer.0
- }};
+fn encode_message<T: wire::Type>(message: wire::Message<T>) -> Vec<u8> {
+ let mut buffer = VecWriter(Vec::with_capacity(MSG_BUF_ALLOC_SIZE));
+ message.type_id().write(&mut buffer).expect("In-memory messages must never fail to serialize");
+ message.write(&mut buffer).expect("In-memory messages must never fail to serialize");
+ buffer.0
}
impl<Descriptor: SocketDescriptor, CM: Deref, OM: Deref, L: Deref, NS: Deref, SM: Deref>
@@ -2068,7 +2067,7 @@ where
for msg in msgs_to_forward.drain(..) {
self.forward_broadcast_msg(
&*peers,
- &msg,
+ msg,
peer_node_id.as_ref().map(|(pk, _)| pk),
false,
);
@@ -2661,22 +2660,25 @@ where
/// unless `allow_large_buffer` is set, in which case the message will be treated as critical
/// and delivered no matter the available buffer space.
fn forward_broadcast_msg(
- &self, peers: &HashMap<Descriptor, Mutex<Peer>>, msg: &BroadcastGossipMessage,
+ &self, peers: &HashMap<Descriptor, Mutex<Peer>>, msg: BroadcastGossipMessage,
except_node: Option<&PublicKey>, allow_large_buffer: bool,
) {
match msg {
- BroadcastGossipMessage::ChannelAnnouncement(ref msg) => {
+ BroadcastGossipMessage::ChannelAnnouncement(msg) => {
log_gossip!(self.logger, "Sending message to all peers except {:?} or the announced channel's counterparties: {:?}", except_node, msg);
- let encoded_msg = encode_msg!(msg);
let our_channel = self.our_node_id == msg.contents.node_id_1
|| self.our_node_id == msg.contents.node_id_2;
-
+ let scid = msg.contents.short_channel_id;
+ let node_id_1 = msg.contents.node_id_1;
+ let node_id_2 = msg.contents.node_id_2;
+ let msg: Message<<CMH::Target as CustomMessageReader>::CustomMessage> =
+ Message::ChannelAnnouncement(msg);
+ let encoded_msg = encode_message(msg);
for (_, peer_mutex) in peers.iter() {
let mut peer = peer_mutex.lock().unwrap();
if !peer.handshake_complete() {
continue;
}
- let scid = msg.contents.short_channel_id;
if !our_channel && !peer.should_forward_channel_announcement(scid) {
continue;
}
@@ -2693,9 +2695,7 @@ where
continue;
}
if let Some((_, their_node_id)) = peer.their_node_id {
- if their_node_id == msg.contents.node_id_1
- || their_node_id == msg.contents.node_id_2
- {
+ if their_node_id == node_id_1 || their_node_id == node_id_2 {
continue;
}
}
@@ -2708,23 +2708,25 @@ where
peer.gossip_broadcast_buffer.push_back(encoded_message);
}
},
- BroadcastGossipMessage::NodeAnnouncement(ref msg) => {
+ BroadcastGossipMessage::NodeAnnouncement(msg) => {
log_gossip!(
self.logger,
"Sending message to all peers except {:?} or the announced node: {:?}",
except_node,
msg
);
- let encoded_msg = encode_msg!(msg);
let our_announcement = self.our_node_id == msg.contents.node_id;
+ let msg_node_id = msg.contents.node_id;
+ let msg: Message<<CMH::Target as CustomMessageReader>::CustomMessage> =
+ Message::NodeAnnouncement(msg);
+ let encoded_msg = encode_message(msg);
for (_, peer_mutex) in peers.iter() {
let mut peer = peer_mutex.lock().unwrap();
if !peer.handshake_complete() {
continue;
}
- let node_id = msg.contents.node_id;
- if !our_announcement && !peer.should_forward_node_announcement(node_id) {
+ if !our_announcement && !peer.should_forward_node_announcement(msg_node_id) {
continue;
}
debug_assert!(peer.their_node_id.is_some());
@@ -2740,7 +2742,7 @@ where
continue;
}
if let Some((_, their_node_id)) = peer.their_node_id {
- if their_node_id == msg.contents.node_id {
+ if their_node_id == msg_node_id {
continue;
}
}
@@ -2760,15 +2762,16 @@ where
except_node,
msg
);
- let encoded_msg = encode_msg!(msg);
- let our_channel = self.our_node_id == *node_id_1 || self.our_node_id == *node_id_2;
-
+ let our_channel = self.our_node_id == node_id_1 || self.our_node_id == node_id_2;
+ let scid = msg.contents.short_channel_id;
+ let msg: Message<<CMH::Target as CustomMessageReader>::CustomMessage> =
+ Message::ChannelUpdate(msg);
+ let encoded_msg = encode_message(msg);
for (_, peer_mutex) in peers.iter() {
let mut peer = peer_mutex.lock().unwrap();
if !peer.handshake_complete() {
continue;
}
- let scid = msg.contents.short_channel_id;
if !our_channel && !peer.should_forward_channel_announcement(scid) {
continue;
}
@@ -3201,7 +3204,7 @@ where
let forward = BroadcastGossipMessage::ChannelAnnouncement(msg);
self.forward_broadcast_msg(
peers,
- &forward,
+ forward,
None,
from_chan_handler,
);
@@ -3222,7 +3225,7 @@ where
};
self.forward_broadcast_msg(
peers,
- &forward,
+ forward,
None,
from_chan_handler,
);
@@ -3246,7 +3249,7 @@ where
};
self.forward_broadcast_msg(
peers,
- &forward,
+ forward,
None,
from_chan_handler,
);
@@ -3265,7 +3268,7 @@ where
let forward = BroadcastGossipMessage::NodeAnnouncement(msg);
self.forward_broadcast_msg(
peers,
- &forward,
+ forward,
None,
from_chan_handler,
);
@@ -3742,7 +3745,7 @@ where
let _ = self.message_handler.route_handler.handle_node_announcement(None, &msg);
self.forward_broadcast_msg(
&*self.peers.read().unwrap(),
- &BroadcastGossipMessage::NodeAnnouncement(msg),
+ BroadcastGossipMessage::NodeAnnouncement(msg),
None,
true,
);
@@ -4557,7 +4560,8 @@ mod tests {
assert_eq!(peer.gossip_broadcast_buffer.len(), 1);
let pending_msg = &peer.gossip_broadcast_buffer[0];
- let expected = encode_msg!(&msg_100);
+ let msg: Message<()> = Message::ChannelUpdate(msg_100);
+ let expected = encode_message(msg);
assert_eq!(expected, pending_msg.fetch_encoded_msg_with_type_pfx());
}
}
diff --git a/lightning/src/ln/wire.rs b/lightning/src/ln/wire.rs
index bc1d83a..9065c49 100644
--- a/lightning/src/ln/wire.rs
+++ b/lightning/src/ln/wire.rs
@@ -425,19 +425,6 @@ where
}
}
-/// Writes a message to the data buffer encoded as a 2-byte big-endian type and a variable-length
-/// payload.
-///
-/// # Errors
-///
-/// Returns an I/O error if the write could not be completed.
-pub(crate) fn write<M: Type + Writeable, W: Writer>(
- message: &M, buffer: &mut W,
-) -> Result<(), io::Error> {
- message.type_id().write(buffer)?;
- message.write(buffer)
-}
-
mod encode {
/// Defines a constant type identifier for reading messages from the wire.
pub trait Encode {
@@ -737,34 +724,6 @@ mod tests {
}
}
- #[test]
- fn write_message_with_type() {
- let message = msgs::Pong { byteslen: 2u16 };
- let mut buffer = Vec::new();
- assert!(write(&message, &mut buffer).is_ok());
-
- let type_length = ::core::mem::size_of::<u16>();
- let (type_bytes, payload_bytes) = buffer.split_at(type_length);
- assert_eq!(u16::from_be_bytes(type_bytes.try_into().unwrap()), msgs::Pong::TYPE);
- assert_eq!(payload_bytes, &ENCODED_PONG[type_length..]);
- }
-
- #[test]
- fn read_message_encoded_with_write() {
- let message = msgs::Pong { byteslen: 2u16 };
- let mut buffer = Vec::new();
- assert!(write(&message, &mut buffer).is_ok());
-
- let decoded_message = read(&mut &buffer[..], &IgnoringMessageHandler {}).unwrap();
- match decoded_message {
- Message::Pong(msgs::Pong { byteslen: 2u16 }) => (),
- Message::Pong(msgs::Pong { byteslen }) => {
- panic!("Expected byteslen {}; found: {}", message.byteslen, byteslen);
- },
- _ => panic!("Expected pong message; found message type: {}", decoded_message.type_id()),
- }
- }
-
#[test]
fn is_even_message_type() {
let message = Message::<()>::Unknown(42);
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.