What changed, and why it matters
This commit adds support for the Bitcoin network's 'pong' message type to the library. A pong is the standard reply to a ping, used to check that a peer is still alive. The change only adds new code for encoding, decoding, and testing this message type; it does not alter existing behavior or fix any vulnerability.
No security action needed. This is a routine feature addition.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces a new Pong type in p2p/src/message.rs, mirroring the existing Ping type. It includes a newtype wrapper around a u64 nonce, an encoder, a decoder, error types, and unit tests for round-trip serialization and construction from a Ping. The implementation is additive only (+89 lines, no deletions) and follows the same patterns already used for Ping.
Changed components
p2p/src/message.rsInspect captured patch +89 / −0
diff --git a/p2p/src/message.rs b/p2p/src/message.rs
index d015488a..44c2572b 100644
--- a/p2p/src/message.rs
+++ b/p2p/src/message.rs
@@ -682,6 +682,80 @@ impl std::error::Error for PingDecoderError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
}
+/// Serializer for Pong
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct Pong(u64);
+
+impl Pong {
+ /// Construct a response [`Pong`] given a received [`Ping`].
+ pub fn from_ping(ping: &Ping) -> Self {
+ let nonce = ping.0;
+ Self(nonce)
+ }
+}
+
+encoding::encoder_newtype! {
+ /// The encoder for the [`Pong`] type.
+ pub struct PongEncoder<'e>(encoding::ArrayEncoder<8>);
+}
+
+impl encoding::Encodable for Pong {
+ type Encoder<'e>
+ = PongEncoder<'e>
+ where
+ Self: 'e;
+ fn encoder(&self) -> Self::Encoder<'_> {
+ let nonce = encoding::ArrayEncoder::without_length_prefix(self.0.to_le_bytes());
+ PongEncoder::new(nonce)
+ }
+}
+
+/// The Decoder for [`Pong`]
+pub struct PongDecoder(encoding::ArrayDecoder<8>);
+
+impl encoding::Decoder for PongDecoder {
+ type Output = Pong;
+ type Error = PongDecoderError;
+
+ #[inline]
+ fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<bool, Self::Error> {
+ self.0.push_bytes(bytes).map_err(PongDecoderError)
+ }
+
+ #[inline]
+ fn end(self) -> Result<Self::Output, Self::Error> {
+ let nonce = self.0.end().map_err(PongDecoderError)?;
+ Ok(Pong(u64::from_le_bytes(nonce)))
+ }
+
+ #[inline]
+ fn read_limit(&self) -> usize { self.0.read_limit() }
+}
+
+impl encoding::Decodable for Pong {
+ type Decoder = PongDecoder;
+ fn decoder() -> Self::Decoder { PongDecoder(encoding::ArrayDecoder::<8>::new()) }
+}
+
+/// An error consensus decoding a [`PongDecoderError`].
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct PongDecoderError(<encoding::ArrayDecoder<8> as encoding::Decoder>::Error);
+
+impl From<Infallible> for PongDecoderError {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+impl fmt::Display for PongDecoderError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ internals::write_err!(f, "pong decoder error"; self.0)
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for PongDecoderError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
+}
+
/// A Network message payload. Proper documentation is available at
/// [Bitcoin Wiki: Protocol Specification](https://en.bitcoin.it/wiki/Protocol_specification)
#[derive(Clone, PartialEq, Eq, Debug)]
@@ -2290,6 +2364,21 @@ mod test {
assert_eq!(decoded_ping, ping);
}
+ #[test]
+ fn roundtrip_encode_decode_pong() {
+ let pong = Pong(314);
+ let encoded_pong = encoding::encode_to_vec(&pong);
+ let decoded_pong = encoding::decode_from_slice::<Pong>(&encoded_pong).unwrap();
+ assert_eq!(decoded_pong, pong);
+ }
+
+ #[test]
+ fn pong_from_ping_constructors() {
+ let ping = Ping::new(314);
+ let pong = Pong::from_ping(&ping);
+ assert_eq!(pong.0, 314);
+ }
+
#[test]
#[rustfmt::skip]
fn serialize_mempool() {
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.