p2p: Implement `encoding` traits for `AddrV2Payload`
What changed, and why it matters
This commit adds standard encoding and decoding support for a new P2P network message container (AddrV2Payload). It is a routine, vector-counterpart follow-up to a previous commit and does not appear to fix or introduce any security issue on its own.
No security action required; review as normal code-quality/functional change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change implements the project’s Encodable and Decodable traits for AddrV2Payload (a Vec<AddrV2Message> wrapper), plus an encoder/decoder newtype and an error type. It mirrors the existing AddrPayload pattern and concludes with an impl_vec_wrapper! macro invocation. There is no evidence of bounds, validation, or parsing logic changes that would affect security.
Changed components
p2p/src/message.rsAddrV2PayloadAddrV2PayloadEncoderAddrV2PayloadDecoderAddrV2PayloadDecoderErrorInspect captured patch +67 / −0
diff --git a/p2p/src/message.rs b/p2p/src/message.rs
index d7c99c52..45c7e587 100644
--- a/p2p/src/message.rs
+++ b/p2p/src/message.rs
@@ -523,6 +523,73 @@ impl std::error::Error for AddrPayloadDecoderError {
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct AddrV2Payload(pub Vec<AddrV2Message>);
+encoding::encoder_newtype! {
+ /// The encoder for an [`AddrV2Payload`].
+ pub struct AddrV2PayloadEncoder<'e>(Encoder2<CompactSizeEncoder, SliceEncoder<'e, AddrV2Message>>);
+}
+
+impl encoding::Encodable for AddrV2Payload {
+ type Encoder<'e>
+ = Encoder2<CompactSizeEncoder, SliceEncoder<'e, AddrV2Message>>
+ where
+ Self: 'e;
+
+ fn encoder(&self) -> Self::Encoder<'_> {
+ Encoder2::new(
+ CompactSizeEncoder::new(self.0.len()), SliceEncoder::without_length_prefix(&self.0)
+ )
+ }
+}
+
+type AddrV2PayloadInnerDecoder = VecDecoder<AddrV2Message>;
+
+/// Decoder type for [`AddrV2Payload`].
+pub struct AddrV2PayloadDecoder(AddrV2PayloadInnerDecoder);
+
+impl encoding::Decoder for AddrV2PayloadDecoder {
+ type Output = AddrV2Payload;
+ type Error = AddrV2PayloadDecoderError;
+
+ #[inline]
+ fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<bool, Self::Error> {
+ self.0.push_bytes(bytes).map_err(AddrV2PayloadDecoderError)
+ }
+
+ #[inline]
+ fn end(self) -> Result<Self::Output, Self::Error> {
+ Ok(AddrV2Payload(self.0.end().map_err(AddrV2PayloadDecoderError)?))
+ }
+
+ #[inline]
+ fn read_limit(&self) -> usize { self.0.read_limit() }
+}
+
+impl encoding::Decodable for AddrV2Payload {
+ type Decoder = AddrV2PayloadDecoder;
+ fn decoder() -> Self::Decoder {
+ AddrV2PayloadDecoder(VecDecoder::new())
+ }
+}
+
+/// An error decoding a [`AddrV2Payload`].
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct AddrV2PayloadDecoderError(<AddrV2PayloadInnerDecoder as encoding::Decoder>::Error);
+
+impl From<Infallible> for AddrV2PayloadDecoderError {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+impl fmt::Display for AddrV2PayloadDecoderError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write_err!(f, "addrv2 payload error"; self.0)
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for AddrV2PayloadDecoderError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
+}
+
impl_vec_wrapper!(InventoryPayload, message_blockdata::Inventory);
impl_vec_wrapper!(AddrPayload, AddrV1Message);
impl_vec_wrapper!(AddrV2Payload, AddrV2Message);
Why this scored 17/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.