p2p: Use V1MessageHeaderDecoder in V1NetworkMessageDecoder
What changed, and why it matters
This is a small internal code cleanup in the Bitcoin peer-to-peer message decoder. It replaces a hand-built four-part header decoder with an existing dedicated header decoder. There is no security bug being fixed; the change is purely for code reuse and slightly better error messages.
No security action required. Treat as a normal refactoring/code-quality change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors V1NetworkMessageDecoder in p2p/src/message.rs to use V1MessageHeaderDecoder instead of manually composing a Decoder4 over ArrayDecoder<4>, CommandStringDecoder, and two more ArrayDecoder<4>s. The decoded values are now read from a V1MessageHeader struct. The payload length conversion is changed from a direct u32 as usize to usize::try_from(header.length).expect(...), which is functionally equivalent on 32-bit and 64-bit platforms and panics only on platforms where usize < 32 bits. No vulnerability is patched.
Changed components
p2p/src/message.rsV1NetworkMessageDecoderV1MessageHeaderDecoderInspect captured patch +12 / −24
diff --git a/p2p/src/message.rs b/p2p/src/message.rs
index 7667a8d1..0bb375f1 100644
--- a/p2p/src/message.rs
+++ b/p2p/src/message.rs
@@ -1369,12 +1369,7 @@ impl encoding::Decoder for NetworkMessageDecoder {
#[derive(Debug, Clone)]
enum DecoderState {
ReadingHeader {
- header_decoder: encoding::Decoder4<
- encoding::ArrayDecoder<4>,
- CommandStringDecoder,
- encoding::ArrayDecoder<4>,
- encoding::ArrayDecoder<4>,
- >,
+ header_decoder: V1MessageHeaderDecoder,
},
ReadingPayload {
magic: Magic,
@@ -1385,7 +1380,7 @@ enum DecoderState {
}
impl Default for DecoderState {
- fn default() -> Self { Self::ReadingHeader { header_decoder: encoding::Decoder4::default() } }
+ fn default() -> Self { Self::ReadingHeader { header_decoder: V1MessageHeaderDecoder::default() } }
}
/// Decoder for [`V1NetworkMessage`].
@@ -1414,12 +1409,7 @@ impl encoding::Decoder for V1NetworkMessageDecoder {
let old_state = core::mem::replace(
&mut self.state,
DecoderState::ReadingHeader {
- header_decoder: encoding::Decoder4::new(
- encoding::ArrayDecoder::new(),
- CommandStringDecoder { inner: encoding::ArrayDecoder::new() },
- encoding::ArrayDecoder::new(),
- encoding::ArrayDecoder::new(),
- ),
+ header_decoder: <V1MessageHeader as encoding::Decode>::decoder(),
},
);
@@ -1427,24 +1417,22 @@ impl encoding::Decoder for V1NetworkMessageDecoder {
unreachable!("we are in ReadingHeader state")
};
- let (magic_bytes, command, payload_len_bytes, checksum) =
- header_decoder.end().map_err(|_| {
- V1NetworkMessageDecoderError(V1NetworkMessageDecoderErrorInner::Header)
- })?;
-
- let length = u32::from_le_bytes(payload_len_bytes);
- let payload_len = length as usize;
+ let header = header_decoder.end().map_err(|_| {
+ V1NetworkMessageDecoderError(V1NetworkMessageDecoderErrorInner::Header)
+ })?;
+ let payload_len = usize::try_from(header.length)
+ .expect("u32 -> usize cast ok for >= 32-bit platforms");
if payload_len > MAX_MSG_SIZE {
return Err(V1NetworkMessageDecoderError(
V1NetworkMessageDecoderErrorInner::PayloadTooLarge,
));
}
- let payload_decoder = NetworkMessageDecoder::new(command, payload_len);
+ let payload_decoder = NetworkMessageDecoder::new(header.command, payload_len);
self.state = DecoderState::ReadingPayload {
- magic: Magic::from_bytes(magic_bytes),
- length,
- checksum,
+ magic: header.magic,
+ length: header.length,
+ checksum: header.checksum,
payload_decoder,
};
Why this scored 12/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.