What changed, and why it matters
This commit adds a new helper function (constructor) to build a Bitcoin P2P network message header. It simply packages existing fields and computes the message checksum automatically. There is no indication it fixes a security bug or introduces a vulnerability; it appears to be a routine API improvement.
No security action required; review as normal code-quality/API change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change introduces V1MessageHeader::new(magic, message, command), which encodes the payload, computes its double-SHA256 4-byte checksum, and returns a populated header struct. It panics if the encoded payload length exceeds u32::MAX. The commit also adds a unit test for a Pong header. No existing behavior is modified.
Changed components
p2p/src/message.rsV1MessageHeaderInspect captured patch +37 / −0
diff --git a/p2p/src/message.rs b/p2p/src/message.rs
index 92ca09d0..bc3f0fb7 100644
--- a/p2p/src/message.rs
+++ b/p2p/src/message.rs
@@ -243,6 +243,27 @@ pub struct V1MessageHeader {
pub checksum: [u8; 4],
}
+impl V1MessageHeader {
+ /// Constructs a new [`V1MessageHeader`] with computed 4 byte checksum.
+ ///
+ /// # Parameters
+ ///
+ /// * `magic` - the network magic bytes.
+ /// * `message` - the message described by header.
+ /// * `command` - the character string which defines the transmitted command.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the payload length exceeds `u32::MAX`.
+ pub fn new<T: encoding::Encode>(magic: Magic, message: &T, command: &'static str) -> Self {
+ let (bytes_hashed, checksum) = sha2_checksum(message);
+ let payload_len = u32::try_from(bytes_hashed).expect("network message use u32 as length");
+ let command = CommandString::try_from_static(command).unwrap();
+
+ Self { magic, command, length: payload_len, checksum }
+ }
+}
+
impl encoding::Encode for V1MessageHeader {
type Encoder<'e>
= V1MessageHeaderEncoder<'e>
@@ -2784,6 +2805,22 @@ mod test {
fn hash(array: [u8; 32]) -> sha256d::Hash { sha256d::Hash::from_byte_array(array) }
+ #[test]
+ fn v1_message_header() {
+ let magic = Magic::BITCOIN;
+ let payload = Pong(314);
+
+ let header = V1MessageHeader::new(magic, &payload, "pong");
+
+ let target_header = V1MessageHeader {
+ magic: Magic::BITCOIN,
+ command: CommandString::try_from_static("pong").unwrap(),
+ length: 8,
+ checksum: [198, 34, 189, 120],
+ };
+ assert_eq!(header, target_header);
+ }
+
#[test]
#[allow(clippy::too_many_lines)]
fn full_round_ser_der_raw_network_message() {
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.