p2p: Implement `encoding` traits for `ShortId`
What changed, and why it matters
This commit adds new encoding and decoding machinery for a 6-byte transaction identifier (ShortId) used in Bitcoin compact block relay (BIP 152). It is a routine feature addition that wires an existing type into a newer internal encoding framework. There is no indication of a bug, vulnerability, or security fix in the diff or commit message.
No security action required. Review as normal code-quality/feature work if desired.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change implements the project’s encoding::Encodable and encoding::Decodable traits for ShortId in p2p/src/bip152.rs. It introduces ShortIdEncoder, ShortIdDecoder, and ShortIdDecoderError, delegating to ArrayEncoder<6> and ArrayDecoder<6> for fixed-length 6-byte serialization. The existing bitcoin::consensus::encode::{Encodable, Decodable} implementation remains unchanged. No bounds, validation, or cryptographic logic is modified.
Changed components
p2p/src/bip152.rsShortId encoding/decodingInspect captured patch +65 / −3
diff --git a/p2p/src/bip152.rs b/p2p/src/bip152.rs
index d592bc68..33de99b6 100644
--- a/p2p/src/bip152.rs
+++ b/p2p/src/bip152.rs
@@ -14,9 +14,7 @@ use std::error;
use arbitrary::{Arbitrary, Unstructured};
use bitcoin::consensus::encode::{self, Decodable, Encodable, ReadExt, WriteExt};
use bitcoin::{block, Block, BlockChecked, BlockHash, Transaction};
-use encoding::{
- CompactSizeDecoder, CompactSizeEncoder, Decoder2, Encoder2, SliceEncoder, VecDecoder,
-};
+use encoding::{ArrayDecoder, ArrayEncoder, CompactSizeDecoder, CompactSizeEncoder, Decoder2, Encoder2, SliceEncoder, VecDecoder};
use hashes::{sha256, siphash24};
use internals::array::ArrayExt as _;
use internals::write_err;
@@ -280,6 +278,70 @@ impl Decodable for ShortId {
}
}
+encoding::encoder_newtype! {
+ /// Encoder type for a [`ShortId`].
+ pub struct ShortIdEncoder<'e>(ArrayEncoder<6>);
+}
+
+impl encoding::Encodable for ShortId {
+ type Encoder<'e> = ShortIdEncoder<'e>;
+
+ fn encoder(&self) -> Self::Encoder<'_> {
+ ShortIdEncoder::new(ArrayEncoder::without_length_prefix(self.to_byte_array()))
+ }
+}
+
+type ShortIdInnerDecoder = ArrayDecoder<6>;
+
+/// Decoder type for a [`ShortId`].
+pub struct ShortIdDecoder(ShortIdInnerDecoder);
+
+impl encoding::Decoder for ShortIdDecoder {
+ type Output = ShortId;
+ type Error = ShortIdDecoderError;
+
+ #[inline]
+ fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<bool, Self::Error> {
+ self.0.push_bytes(bytes).map_err(ShortIdDecoderError)
+ }
+
+ #[inline]
+ fn end(self) -> Result<Self::Output, Self::Error> {
+ let arr = self.0.end().map_err(ShortIdDecoderError)?;
+ Ok(ShortId(arr))
+ }
+
+ #[inline]
+ fn read_limit(&self) -> usize { self.0.read_limit() }
+}
+
+impl encoding::Decodable for ShortId {
+ type Decoder = ShortIdDecoder;
+
+ fn decoder() -> Self::Decoder {
+ ShortIdDecoder(ShortIdInnerDecoder::new())
+ }
+}
+
+/// An error decoding a [`ShortId`].
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ShortIdDecoderError(<ShortIdInnerDecoder as encoding::Decoder>::Error);
+
+impl From<Infallible> for ShortIdDecoderError {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+impl fmt::Display for ShortIdDecoderError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write_err!(f, "shortid error"; self.0)
+ }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for ShortIdDecoderError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
+}
+
/// A structure to relay a block header, short IDs, and a select few transactions.
///
/// A [`HeaderAndShortIds`] structure is used to relay a block header, the short
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.