p2p: Implement `encoding` traits for `ProtocolVersion`
What changed, and why it matters
This commit adds new serialization/deserialization code for the `ProtocolVersion` type in the peer-to-peer networking module. It is a routine feature addition that mirrors existing patterns and does not fix any known bug or security issue.
No security action required; review as normal code-quality change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change implements the new encoding::Encodable and encoding::Decodable traits for ProtocolVersion, providing an encoder/decoder pair that serializes the inner u32 as 4 little-endian bytes. It also adds a trivial ProtocolVersionDecoderError wrapper around the infallible ArrayDecoder<4> error. The implementation is consistent with surrounding code and introduces no behavioral changes to existing consensus encoding.
Changed components
p2p/src/lib.rsProtocolVersionProtocolVersionEncoderProtocolVersionDecoderProtocolVersionDecoderErrorInspect captured patch +70 / −1
diff --git a/p2p/src/lib.rs b/p2p/src/lib.rs
index 2d51fb45..b9fa32ea 100644
--- a/p2p/src/lib.rs
+++ b/p2p/src/lib.rs
@@ -30,6 +30,7 @@ extern crate std;
use alloc::borrow::ToOwned;
use alloc::string::String;
use core::borrow::{Borrow, BorrowMut};
+use core::convert::Infallible;
use core::str::FromStr;
use core::{fmt, ops};
@@ -38,7 +39,7 @@ use arbitrary::{Arbitrary, Unstructured};
use bitcoin::consensus::encode::{self, Decodable, Encodable};
use bitcoin::network::{Network, Params, TestnetVersion};
use hex::FromHex;
-use internals::impl_to_hex_from_lower_hex;
+use internals::{impl_to_hex_from_lower_hex, write_err};
use io::{BufRead, Write};
#[rustfmt::skip]
@@ -110,6 +111,74 @@ impl Decodable for ProtocolVersion {
}
}
+encoding::encoder_newtype! {
+ /// The encoder for the [`ProtocolVersion`] type.
+ pub struct ProtocolVersionEncoder(encoding::ArrayEncoder<4>);
+}
+
+impl encoding::Encodable for ProtocolVersion {
+ type Encoder<'e> = ProtocolVersionEncoder;
+ fn encoder(&self) -> Self::Encoder<'_> {
+ ProtocolVersionEncoder(encoding::ArrayEncoder::without_length_prefix(
+ self.0.to_le_bytes(),
+ ))
+ }
+}
+
+/// The decoder for the [`ProtocolVersion`] type.
+pub struct ProtocolVersionDecoder(encoding::ArrayDecoder<4>);
+
+impl ProtocolVersionDecoder {
+ /// Constructs a new [`ProtocolVersion`] decoder.
+ pub const fn new() -> Self { Self(encoding::ArrayDecoder::new()) }
+}
+
+impl Default for ProtocolVersionDecoder {
+ fn default() -> Self { Self::new() }
+}
+
+impl encoding::Decoder for ProtocolVersionDecoder {
+ type Output = ProtocolVersion;
+ type Error = ProtocolVersionDecoderError;
+
+ #[inline]
+ fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<bool, Self::Error> {
+ Ok(self.0.push_bytes(bytes).map_err(ProtocolVersionDecoderError)?)
+ }
+
+ #[inline]
+ fn end(self) -> Result<Self::Output, Self::Error> {
+ let n = u32::from_le_bytes(self.0.end().map_err(ProtocolVersionDecoderError)?);
+ Ok(ProtocolVersion(n))
+ }
+
+ #[inline]
+ fn read_limit(&self) -> usize { self.0.read_limit() }
+}
+
+impl encoding::Decodable for ProtocolVersion {
+ type Decoder = ProtocolVersionDecoder;
+ fn decoder() -> Self::Decoder { ProtocolVersionDecoder(encoding::ArrayDecoder::<4>::new()) }
+}
+
+/// An error consensus decoding an `ProtocolVersion`.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ProtocolVersionDecoderError(<encoding::ArrayDecoder<4> as encoding::Decoder>::Error);
+
+impl From<Infallible> for ProtocolVersionDecoderError {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+impl fmt::Display for ProtocolVersionDecoderError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write_err!(f, "protocolversion error"; self.0)
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for ProtocolVersionDecoderError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
+}
/// Flags to indicate which network services a node supports.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ServiceFlags(u64);
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.