p2p: Replace decoder definitions with decoder_newtype macro
What changed, and why it matters
This commit is a large internal cleanup in the P2P networking code. It replaces many hand-written decoder definitions with a shared macro called decoder_newtype!. There is no change to how data is parsed, validated, or what limits are enforced; the same logic is just written more concisely. It does not appear to fix or introduce any security vulnerability.
No security action required. Treat as normal refactoring. If reviewing, verify the macro definition in include/decoder_newtype.rs expands to the same trait implementation pattern as the removed code, and that no behavioral changes were introduced during the mechanical conversion.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors rust-bitcoin’s p2p crate to use a new decoder_newtype! macro (included from p2p/include -> ../include/decoder_newtype.rs). It mechanically replaces explicit impl encoding::Decoder blocks for newtype decoder wrappers across address.rs, bip152.rs, lib.rs, merkle_tree.rs, message.rs, message_blockdata.rs, message_bloom.rs, message_compact_blocks.rs, message_erlay.rs, message_filter.rs, and message_network.rs. The generated code preserves the original push_bytes, end, read_limit, Default, Clone, and Debug behavior. A few minor incidental changes appear (e.g., moving helper methods out of the impl Decoder block in AddrV2Decoder, adding Header import in merkle_tree.rs, adding VecDecoderError and AddrV2MessageDecoderError imports in message.rs, and reordering VersionMessageDecoder/VersionMessageInnerDecoder definitions), but the decoding semantics remain unchanged.
Changed components
p2p/src/address.rsp2p/src/bip152.rsp2p/src/lib.rsp2p/src/merkle_tree.rsp2p/src/message.rsp2p/src/message_blockdata.rsp2p/src/message_bloom.rsp2p/src/message_compact_blocks.rsp2p/src/message_erlay.rsp2p/src/message_filter.rsp2p/src/message_network.rsp2p/include (symlink to ../include)Inspect captured patch +478 / −928
diff --git a/p2p/include b/p2p/include
new file mode 120000
index 00000000..f5030fe8
--- /dev/null
+++ b/p2p/include
@@ -0,0 +1 @@
+../include
\ No newline at end of file
diff --git a/p2p/src/address.rs b/p2p/src/address.rs
index 6372987b..b3abb3eb 100644
--- a/p2p/src/address.rs
+++ b/p2p/src/address.rs
@@ -158,28 +158,18 @@ type AddressInnerDecoder = encoding::Decoder3<
encoding::ArrayDecoder<2>,
>;
-/// The Decoder for [`Address`].
-#[derive(Debug, Default, Clone)]
-pub struct AddressDecoder(AddressInnerDecoder);
-
-impl encoding::Decoder for AddressDecoder {
- type Output = Address;
- type Error = AddressDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(AddressDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (services, raw_address, port) = self.0.end().map_err(AddressDecoderError)?;
+crate::decoder_newtype! {
+ /// The Decoder for [`Address`].
+ #[derive(Debug, Default, Clone)]
+ pub struct AddressDecoder(AddressInnerDecoder);
+
+ fn end(
+ result: Result<(ServiceFlags, [u8; 16], [u8; 2]), <AddressInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<Address, AddressDecoderError> {
+ let (services, raw_address, port) = result.map_err(AddressDecoderError)?;
let address = address_from_u8(raw_address);
Ok(Address { services, address, port: u16::from_be_bytes(port) })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for Address {
@@ -214,28 +204,18 @@ impl encoding::Encode for AddrV1Message {
type AddrV1MessageInnerDecoder = Decoder2<ArrayDecoder<4>, AddressDecoder>;
-/// The decoder for an [`AddrV1Message`].
-#[derive(Debug, Default, Clone)]
-pub struct AddrV1MessageDecoder(AddrV1MessageInnerDecoder);
-
-impl encoding::Decoder for AddrV1MessageDecoder {
- type Output = AddrV1Message;
- type Error = AddrV1MessageDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(AddrV1MessageDecoderError)
- }
+crate::decoder_newtype! {
+ /// The decoder for an [`AddrV1Message`].
+ #[derive(Debug, Default, Clone)]
+ pub struct AddrV1MessageDecoder(AddrV1MessageInnerDecoder);
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (time, address) = self.0.end().map_err(AddrV1MessageDecoderError)?;
+ fn end(
+ result: Result<([u8; 4], Address), <AddrV1MessageInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<AddrV1Message, AddrV1MessageDecoderError> {
+ let (time, address) = result.map_err(AddrV1MessageDecoderError)?;
let time = u32::from_le_bytes(time);
Ok(AddrV1Message { time, address })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for AddrV1Message {
@@ -479,62 +459,19 @@ impl encoding::Encode for AddrV2 {
type AddrV2InnerDecoder = Decoder2<ArrayDecoder<1>, ByteVecDecoder>;
-/// The decoder type for an [`AddrV2`] type.
-#[derive(Debug, Default, Clone)]
-pub struct AddrV2Decoder(AddrV2InnerDecoder);
-
-impl AddrV2Decoder {
- #[inline]
- const fn be_bytes_to_segments(bytes: [u8; 16]) -> [u16; 8] {
- [
- u16::from_be_bytes([bytes[0], bytes[1]]),
- u16::from_be_bytes([bytes[2], bytes[3]]),
- u16::from_be_bytes([bytes[4], bytes[5]]),
- u16::from_be_bytes([bytes[6], bytes[7]]),
- u16::from_be_bytes([bytes[8], bytes[9]]),
- u16::from_be_bytes([bytes[10], bytes[11]]),
- u16::from_be_bytes([bytes[12], bytes[13]]),
- u16::from_be_bytes([bytes[14], bytes[15]]),
- ]
- }
-
- #[inline]
- const fn ipv6_from_segments(segments: [u16; 8]) -> Ipv6Addr {
- Ipv6Addr::new(
- segments[0],
- segments[1],
- segments[2],
- segments[3],
- segments[4],
- segments[5],
- segments[6],
- segments[7],
- )
- }
-
- #[inline]
- fn to_fixed_size_slice<const N: usize>(
- addr_bytes: Vec<u8>,
- ) -> Result<[u8; N], AddrV2DecoderError> {
- addr_bytes.try_into().map_err(|e: Vec<u8>| AddrV2DecoderError::InvalidAddressLength {
- expected: N,
- got: e.len(),
- })
- }
-}
-
-impl encoding::Decoder for AddrV2Decoder {
- type Output = AddrV2;
- type Error = AddrV2DecoderError;
+crate::decoder_newtype! {
+ /// The decoder type for an [`AddrV2`] type.
+ #[derive(Debug, Default, Clone)]
+ pub struct AddrV2Decoder(AddrV2InnerDecoder);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(AddrV2DecoderError::Decoder)
+ fn map_push_bytes_err(err: <AddrV2InnerDecoder as encoding::Decoder>::Error) -> AddrV2DecoderError {
+ AddrV2DecoderError::Decoder(err)
}
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (net_type, addr_bytes) = self.0.end().map_err(AddrV2DecoderError::Decoder)?;
+ fn end(
+ result: Result<([u8; 1], Vec<u8>), <AddrV2InnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<AddrV2, AddrV2DecoderError> {
+ let (net_type, addr_bytes) = result.map_err(AddrV2DecoderError::Decoder)?;
if addr_bytes.len() > 512 {
return Err(AddrV2DecoderError::InvalidAddressLength {
expected: 512,
@@ -575,9 +512,46 @@ impl encoding::Decoder for AddrV2Decoder {
any => Ok(AddrV2::Unknown(any, addr_bytes)),
}
}
+}
+
+impl AddrV2Decoder {
+ #[inline]
+ const fn be_bytes_to_segments(bytes: [u8; 16]) -> [u16; 8] {
+ [
+ u16::from_be_bytes([bytes[0], bytes[1]]),
+ u16::from_be_bytes([bytes[2], bytes[3]]),
+ u16::from_be_bytes([bytes[4], bytes[5]]),
+ u16::from_be_bytes([bytes[6], bytes[7]]),
+ u16::from_be_bytes([bytes[8], bytes[9]]),
+ u16::from_be_bytes([bytes[10], bytes[11]]),
+ u16::from_be_bytes([bytes[12], bytes[13]]),
+ u16::from_be_bytes([bytes[14], bytes[15]]),
+ ]
+ }
+
+ #[inline]
+ const fn ipv6_from_segments(segments: [u16; 8]) -> Ipv6Addr {
+ Ipv6Addr::new(
+ segments[0],
+ segments[1],
+ segments[2],
+ segments[3],
+ segments[4],
+ segments[5],
+ segments[6],
+ segments[7],
+ )
+ }
#[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
+ fn to_fixed_size_slice<const N: usize>(
+ addr_bytes: Vec<u8>,
+ ) -> Result<[u8; N], AddrV2DecoderError> {
+ addr_bytes.try_into().map_err(|e: Vec<u8>| AddrV2DecoderError::InvalidAddressLength {
+ expected: N,
+ got: e.len(),
+ })
+ }
}
impl encoding::Decode for AddrV2 {
@@ -647,30 +621,23 @@ impl encoding::Encode for AddrV2Message {
type AddrV2MessageInnerDecoder =
Decoder4<ArrayDecoder<4>, CompactSizeU64Decoder, AddrV2Decoder, ArrayDecoder<2>>;
-/// The decoder for an [`AddrV2Message`].
-#[derive(Debug, Default, Clone)]
-pub struct AddrV2MessageDecoder(AddrV2MessageInnerDecoder);
-
-impl encoding::Decoder for AddrV2MessageDecoder {
- type Output = AddrV2Message;
- type Error = AddrV2MessageDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(AddrV2MessageDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (time, services, addr, port) = self.0.end().map_err(AddrV2MessageDecoderError)?;
+crate::decoder_newtype! {
+ /// The decoder for an [`AddrV2Message`].
+ #[derive(Debug, Default, Clone)]
+ pub struct AddrV2MessageDecoder(AddrV2MessageInnerDecoder);
+
+ fn end(
+ result: Result<
+ <AddrV2MessageInnerDecoder as encoding::Decoder>::Output,
+ <AddrV2MessageInnerDecoder as encoding::Decoder>::Error,
+ >
+ ) -> Result<AddrV2Message, AddrV2MessageDecoderError> {
+ let (time, services, addr, port) = result.map_err(AddrV2MessageDecoderError)?;
let services = ServiceFlags(services);
let time = u32::from_le_bytes(time);
let port = u16::from_be_bytes(port);
Ok(AddrV2Message { time, services, addr, port })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for AddrV2Message {
diff --git a/p2p/src/bip152.rs b/p2p/src/bip152.rs
index 8b212cbf..74c8ca81 100644
--- a/p2p/src/bip152.rs
+++ b/p2p/src/bip152.rs
@@ -11,7 +11,7 @@ use core::convert;
use arbitrary::{Arbitrary, Unstructured};
use encoding::{
ArrayDecoder, ArrayEncoder, CompactSizeDecoder, CompactSizeEncoder, Decoder2, Decoder4,
- Encoder2, Encoder4, SliceEncoder, VecDecoder, DecoderStatus,
+ Encoder2, Encoder4, SliceEncoder, VecDecoder,
};
use hashes::{sha256, siphash24, HashEngine};
use internals::array::ArrayExt as _;
@@ -74,37 +74,23 @@ impl encoding::Encode for PrefilledTransaction {
type PrefilledTransactionInnerDecoder = Decoder2<CompactSizeDecoder, TransactionDecoder>;
-/// The decoder for a [`PrefilledTransaction`] message.
-#[derive(Debug, Default, Clone)]
-pub struct PrefilledTransactionDecoder(PrefilledTransactionInnerDecoder);
+crate::decoder_newtype! {
+ /// The decoder for a [`PrefilledTransaction`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct PrefilledTransactionDecoder(PrefilledTransactionInnerDecoder);
-impl PrefilledTransactionDecoder {
- fn err_from_inner(
- inner: <PrefilledTransactionInnerDecoder as encoding::Decoder>::Error,
- ) -> PrefilledTransactionDecoderError {
- PrefilledTransactionDecoderError::Decoder(inner)
- }
-}
-
-impl encoding::Decoder for PrefilledTransactionDecoder {
- type Output = PrefilledTransaction;
- type Error = PrefilledTransactionDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(Self::err_from_inner)
+ fn map_push_bytes_err(err: <PrefilledTransactionInnerDecoder as encoding::Decoder>::Error) -> PrefilledTransactionDecoderError {
+ PrefilledTransactionDecoderError::Decoder(err)
}
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (cs, tx) = self.0.end().map_err(Self::err_from_inner)?;
- let idx =
- u16::try_from(cs).map_err(|_| PrefilledTransactionDecoderError::InvalidIndex(cs))?;
+ fn end(
+ result: Result<(usize, Transaction), <PrefilledTransactionInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<PrefilledTransaction, PrefilledTransactionDecoderError> {
+ let (cs, tx) = result.map_err(PrefilledTransactionDecoderError::Decoder)?;
+ let idx = u16::try_from(cs)
+ .map_err(|_| PrefilledTransactionDecoderError::InvalidIndex(cs))?;
Ok(PrefilledTransaction { idx, tx })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for PrefilledTransaction {
@@ -204,27 +190,17 @@ impl encoding::Encode for ShortId {
type ShortIdInnerDecoder = ArrayDecoder<6>;
-/// Decoder type for a [`ShortId`].
-#[derive(Debug, Default, Clone)]
-pub struct ShortIdDecoder(ShortIdInnerDecoder);
-
-impl encoding::Decoder for ShortIdDecoder {
- type Output = ShortId;
- type Error = ShortIdDecoderError;
+crate::decoder_newtype! {
+ /// Decoder type for a [`ShortId`].
+ #[derive(Debug, Default, Clone)]
+ pub struct ShortIdDecoder(ShortIdInnerDecoder);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, 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)?;
+ fn end(
+ result: Result<[u8; 6], <ShortIdInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<ShortId, ShortIdDecoderError> {
+ let arr = result.map_err(ShortIdDecoderError)?;
Ok(ShortId(arr))
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for ShortId {
@@ -290,43 +266,28 @@ impl encoding::Encode for HeaderAndShortIds {
type HeaderAndShortIdsInnerDecoder =
Decoder4<HeaderDecoder, ArrayDecoder<8>, VecDecoder<ShortId>, VecDecoder<PrefilledTransaction>>;
-/// Decoder type for the [`HeaderAndShortIds`] message.
-#[derive(Debug, Default, Clone)]
-pub struct HeaderAndShortIdsDecoder(HeaderAndShortIdsInnerDecoder);
-
-impl HeaderAndShortIdsDecoder {
- fn err_from_inner(
- inner: <HeaderAndShortIdsInnerDecoder as encoding::Decoder>::Error,
- ) -> HeaderAndShortIdsDecoderError {
- HeaderAndShortIdsDecoderError::Decoder(inner)
- }
-}
-
-impl encoding::Decoder for HeaderAndShortIdsDecoder {
- type Output = HeaderAndShortIds;
- type Error = HeaderAndShortIdsDecoderError;
+crate::decoder_newtype! {
+ /// Decoder type for the [`HeaderAndShortIds`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct HeaderAndShortIdsDecoder(HeaderAndShortIdsInnerDecoder);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(Self::err_from_inner)
+ fn map_push_bytes_err(err: <HeaderAndShortIdsInnerDecoder as encoding::Decoder>::Error) -> HeaderAndShortIdsDecoderError {
+ HeaderAndShortIdsDecoderError::Decoder(err)
}
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (header, nonce, short_ids, prefilled_txs) =
- self.0.end().map_err(Self::err_from_inner)?;
- let overflow_check = short_ids
- .len()
- .checked_add(prefilled_txs.len())
- .ok_or(HeaderAndShortIdsDecoderError::IndexOverflow)?;
+ fn end(
+ result: Result<
+ <HeaderAndShortIdsInnerDecoder as encoding::Decoder>::Output,
+ <HeaderAndShortIdsInnerDecoder as encoding::Decoder>::Error
+ >
+ ) -> Result<HeaderAndShortIds, HeaderAndShortIdsDecoderError> {
+ let (header, nonce, short_ids, prefilled_txs) = result.map_err(HeaderAndShortIdsDecoderError::Decoder)?;
+ let overflow_check = short_ids.len().checked_add(prefilled_txs.len()).ok_or(HeaderAndShortIdsDecoderError::IndexOverflow)?;
if overflow_check > u16::MAX.into() {
return Err(HeaderAndShortIdsDecoderError::IndexOverflow);
}
Ok(HeaderAndShortIds { header, nonce: u64::from_le_bytes(nonce), short_ids, prefilled_txs })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for HeaderAndShortIds {
@@ -427,23 +388,21 @@ impl encoding::Encode for Offset {
fn encoder(&self) -> Self::Encoder<'_> { CompactSizeEncoder::new(self.0) }
}
-#[derive(Debug, Default, Clone)]
-struct OffsetDecoder(CompactSizeDecoder);
+type OffsetDecoderError = encoding::CompactSizeDecoderError;
-impl encoding::Decoder for OffsetDecoder {
- type Output = Offset;
- type Error = <CompactSizeDecoder as encoding::Decoder>::Error;
+crate::decoder_newtype! {
+ #[derive(Debug, Default, Clone)]
+ struct OffsetDecoder(CompactSizeDecoder);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes)
+ fn map_push_bytes_err(err: encoding::CompactSizeDecoderError) -> OffsetDecoderError {
+ err
}
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> { Ok(Offset(self.0.end()?)) }
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
+ fn end(
+ result: Result<usize, encoding::CompactSizeDecoderError>
+ ) -> Result<Offset, OffsetDecoderError> {
+ result.map(Offset)
+ }
}
impl encoding::Decode for Offset {
@@ -537,27 +496,17 @@ impl encoding::Encode for BlockTransactionsRequest {
type BlockTransactionsRequestInnerDecoder = Decoder2<BlockHashDecoder, VecDecoder<Offset>>;
-/// The encoder type for a [`BlockTransactionsRequest`].
-#[derive(Debug, Default, Clone)]
-pub struct BlockTransactionsRequestDecoder(BlockTransactionsRequestInnerDecoder);
-
-impl encoding::Decoder for BlockTransactionsRequestDecoder {
- type Output = BlockTransactionsRequest;
- type Error = BlockTransactionsRequestDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(BlockTransactionsRequestDecoderError)
- }
+crate::decoder_newtype! {
+ /// The decoder type for a [`BlockTransactionsRequest`].
+ #[derive(Debug, Default, Clone)]
+ pub struct BlockTransactionsRequestDecoder(BlockTransactionsRequestInnerDecoder);
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (block_hash, offsets) = self.0.end().map_err(BlockTransactionsRequestDecoderError)?;
+ fn end(
+ result: Result<(BlockHash, Vec<Offset>), <BlockTransactionsRequestInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<BlockTransactionsRequest, BlockTransactionsRequestDecoderError> {
+ let (block_hash, offsets) = result.map_err(BlockTransactionsRequestDecoderError)?;
Ok(BlockTransactionsRequest { block_hash, offsets })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for BlockTransactionsRequest {
@@ -604,27 +553,17 @@ impl encoding::Encode for BlockTransactions {
type BlockTransactionsInnerDecoder = Decoder2<BlockHashDecoder, VecDecoder<Transaction>>;
-/// Decoder type for a [`BlockTransactions`] message.
-#[derive(Debug, Default, Clone)]
-pub struct BlockTransactionsDecoder(BlockTransactionsInnerDecoder);
-
-impl encoding::Decoder for BlockTransactionsDecoder {
- type Output = BlockTransactions;
- type Error = BlockTransactionsDecoderError;
+crate::decoder_newtype! {
+ /// Decoder type for a [`BlockTransactions`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct BlockTransactionsDecoder(BlockTransactionsInnerDecoder);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(BlockTransactionsDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (block_hash, transactions) = self.0.end().map_err(BlockTransactionsDecoderError)?;
+ fn end(
+ result: Result<(BlockHash, Vec<Transaction>), <BlockTransactionsInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<BlockTransactions, BlockTransactionsDecoderError> {
+ let (block_hash, transactions) = result.map_err(BlockTransactionsDecoderError)?;
Ok(BlockTransactions { block_hash, transactions })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for BlockTransactions {
diff --git a/p2p/src/lib.rs b/p2p/src/lib.rs
index e45f45f6..10d0d892 100644
--- a/p2p/src/lib.rs
+++ b/p2p/src/lib.rs
@@ -128,36 +128,20 @@ impl encoding::Encode for ProtocolVersion {
}
}
-/// The decoder for the [`ProtocolVersion`] type.
-#[derive(Debug, Clone)]
-pub struct ProtocolVersionDecoder(encoding::ArrayDecoder<4>);
+crate::decoder_newtype! {
+ /// The decoder for the [`ProtocolVersion`] type.
+ #[derive(Debug, Clone)]
+ 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<encoding::DecoderStatus, Self::Error> {
- 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)?);
+ fn end(
+ result: Result<[u8; 4], encoding::UnexpectedEofError>
+ ) -> Result<ProtocolVersion, ProtocolVersionDecoderError> {
+ let n = u32::from_le_bytes(result.map_err(ProtocolVersionDecoderError)?);
Ok(ProtocolVersion(n))
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for ProtocolVersion {
@@ -322,36 +306,20 @@ impl encoding::Encode for ServiceFlags {
}
}
-/// The decoder for the [`ServiceFlags`] type.
-#[derive(Debug, Clone)]
-pub struct ServiceFlagsDecoder(encoding::ArrayDecoder<8>);
+crate::decoder_newtype! {
+ /// The decoder for the [`ServiceFlags`] type.
+ #[derive(Debug, Clone)]
+ pub struct ServiceFlagsDecoder(encoding::ArrayDecoder<8>);
-impl ServiceFlagsDecoder {
/// Constructs a new [`ServiceFlags`] decoder.
pub const fn new() -> Self { Self(encoding::ArrayDecoder::new()) }
-}
-impl Default for ServiceFlagsDecoder {
- fn default() -> Self { Self::new() }
-}
-
-impl encoding::Decoder for ServiceFlagsDecoder {
- type Output = ServiceFlags;
- type Error = ServiceFlagsDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(ServiceFlagsDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let n = u64::from_le_bytes(self.0.end().map_err(ServiceFlagsDecoderError)?);
+ fn end(
+ result: Result<[u8; 8], encoding::UnexpectedEofError>
+ ) -> Result<ServiceFlags, ServiceFlagsDecoderError> {
+ let n = u64::from_le_bytes(result.map_err(ServiceFlagsDecoderError)?);
Ok(ServiceFlags(n))
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for ServiceFlags {
@@ -461,27 +429,17 @@ impl encoding::Encode for Magic {
type MagicInnerDecoder = ArrayDecoder<4>;
-/// The decoder type for a network [`Magic`].
-#[derive(Debug, Default, Clone)]
-pub struct MagicDecoder(MagicInnerDecoder);
+crate::decoder_newtype! {
+ /// The decoder type for a network [`Magic`].
+ #[derive(Debug, Default, Clone)]
+ pub struct MagicDecoder(MagicInnerDecoder);
-impl encoding::Decoder for MagicDecoder {
- type Output = Magic;
- type Error = MagicDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(MagicDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let bytes = self.0.end().map_err(MagicDecoderError)?;
+ fn end(
+ result: Result<[u8; 4], <MagicInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<Magic, MagicDecoderError> {
+ let bytes = result.map_err(MagicDecoderError)?;
Ok(Magic::from_bytes(bytes))
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for Magic {
@@ -535,6 +493,9 @@ impl<'a> Arbitrary<'a> for Magic {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> { Ok(Self(u.arbitrary()?)) }
}
+// decoder_newtype! macro
+include!("../include/decoder_newtype.rs");
+
#[cfg(test)]
mod tests {
use alloc::string::ToString;
diff --git a/p2p/src/merkle_tree.rs b/p2p/src/merkle_tree.rs
index 76a5eff4..063d495a 100644
--- a/p2p/src/merkle_tree.rs
+++ b/p2p/src/merkle_tree.rs
@@ -19,7 +19,7 @@ use encoding::{
EncoderStatus, Encoder2, Encoder3, SliceEncoder, VecDecoder,
};
use internals::ToU64 as _;
-use primitives::block::{self, Block, Checked, HeaderDecoder, HeaderEncoder};
+use primitives::block::{self, Block, Checked, Header, HeaderDecoder, HeaderEncoder};
use primitives::merkle_tree::TxMerkleNode;
use primitives::transaction::{Transaction, Txid};
use primitives::Weight;
@@ -143,27 +143,17 @@ impl encoding::Encode for MerkleBlock {
type MerkleBlockInnerDecoder = Decoder2<HeaderDecoder, PartialMerkleTreeDecoder>;
-/// The decoder for a [`MerkleBlock`].
-#[derive(Debug, Default, Clone)]
-pub struct MerkleBlockDecoder(MerkleBlockInnerDecoder);
+crate::decoder_newtype! {
+ /// The decoder for a [`MerkleBlock`].
+ #[derive(Debug, Default, Clone)]
+ pub struct MerkleBlockDecoder(MerkleBlockInnerDecoder);
-impl encoding::Decoder for MerkleBlockDecoder {
- type Output = MerkleBlock;
- type Error = MerkleBlockDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(MerkleBlockDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (header, txn) = self.0.end().map_err(MerkleBlockDecoderError)?;
+ fn end(
+ result: Result<(Header, PartialMerkleTree), <MerkleBlockInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<MerkleBlock, MerkleBlockDecoderError> {
+ let (header, txn) = result.map_err(MerkleBlockDecoderError)?;
Ok(MerkleBlock { header, txn })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for MerkleBlock {
@@ -511,23 +501,19 @@ impl encoding::Encode for PartialMerkleTree {
type PartialMerkleTreeInnerDecoder =
Decoder3<ArrayDecoder<4>, VecDecoder<TxMerkleNode>, ByteVecDecoder>;
-/// The decoder type for a [`PartialMerkleTree`].
-#[derive(Debug, Default, Clone)]
-pub struct PartialMerkleTreeDecoder(PartialMerkleTreeInnerDecoder);
-
-impl encoding::Decoder for PartialMerkleTreeDecoder {
- type Output = PartialMerkleTree;
- type Error = PartialMerkleTreeDecoderError;
+crate::decoder_newtype! {
+ /// The decoder type for a [`PartialMerkleTree`].
+ #[derive(Debug, Default, Clone)]
+ pub struct PartialMerkleTreeDecoder(PartialMerkleTreeInnerDecoder);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(PartialMerkleTreeDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
+ fn end(
+ result: Result<
+ <PartialMerkleTreeInnerDecoder as encoding::Decoder>::Output,
+ <PartialMerkleTreeInnerDecoder as encoding::Decoder>::Error,
+ >
+ ) -> Result<PartialMerkleTree, PartialMerkleTreeDecoderError> {
let (num_transactions, hashes, compress_bit_vec) =
- self.0.end().map_err(PartialMerkleTreeDecoderError)?;
+ result.map_err(PartialMerkleTreeDecoderError)?;
let num_transactions = u32::from_le_bytes(num_transactions);
let mut bits = Vec::with_capacity(compress_bit_vec.len());
for byte in compress_bit_vec {
@@ -537,9 +523,6 @@ impl encoding::Decoder for PartialMerkleTreeDecoder {
}
Ok(PartialMerkleTree { num_transactions, bits, hashes })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for PartialMerkleTree {
diff --git a/p2p/src/message.rs b/p2p/src/message.rs
index 7497da0c..155efeb2 100644
--- a/p2p/src/message.rs
+++ b/p2p/src/message.rs
@@ -15,15 +15,15 @@ use core::{fmt, mem};
use arbitrary::{Arbitrary, Unstructured};
use encoding::{
self, ArrayDecoder, ArrayEncoder, BytesEncoder, CompactSizeEncoder, Decoder2, EncoderStatus,
- Encoder2, SliceEncoder, VecDecoder,
+ Encoder2, SliceEncoder, VecDecoder, VecDecoderError,
};
use hashes::{sha256d, HashEngine};
-use primitives::block::{self, HeaderDecoder, HeaderEncoder};
+use primitives::block::{self, Header, HeaderDecoder, HeaderEncoder};
use primitives::transaction;
use units::{Amount, FeeRate};
use self::error::V1NetworkMessageDecoderErrorInner;
-use crate::address::{AddrV1Message, AddrV2Message};
+use crate::address::{AddrV1Message, AddrV2Message, AddrV2MessageDecoderError};
use crate::merkle_tree::MerkleBlock;
use crate::message_erlay::{SendTxRcnCl, SendTxRcnClDecoder};
use crate::{
@@ -269,23 +269,19 @@ type V1MessageHeaderInnerDecoder = encoding::Decoder4<
encoding::ArrayDecoder<4>,
>;
-/// The Decoder for `V1MessageHeader`
-#[derive(Debug, Default, Clone)]
-pub struct V1MessageHeaderDecoder(V1MessageHeaderInnerDecoder);
-
-impl encoding::Decoder for V1MessageHeaderDecoder {
- type Output = V1MessageHeader;
- type Error = V1MessageHeaderDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(V1MessageHeaderDecoderError)
- }
+crate::decoder_newtype! {
+ /// The Decoder for `V1MessageHeader`
+ #[derive(Debug, Default, Clone)]
+ pub struct V1MessageHeaderDecoder(V1MessageHeaderInnerDecoder);
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
+ fn end(
+ result: Result<
+ <V1MessageHeaderInnerDecoder as encoding::Decoder>::Output,
+ <V1MessageHeaderInnerDecoder as encoding::Decoder>::Error,
+ >
+ ) -> Result<V1MessageHeader, V1MessageHeaderDecoderError> {
let (magic, command, length, checksum) =
- self.0.end().map_err(V1MessageHeaderDecoderError)?;
+ result.map_err(V1MessageHeaderDecoderError)?;
Ok(V1MessageHeader {
magic: Magic(magic),
command,
@@ -293,9 +289,6 @@ impl encoding::Decoder for V1MessageHeaderDecoder {
checksum,
})
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for V1MessageHeader {
@@ -334,26 +327,16 @@ impl encoding::Encode for InventoryPayload {
type InventoryInnerDecoder = VecDecoder<message_blockdata::Inventory>;
-/// Decoder type for [`InventoryPayload`].
-#[derive(Debug, Default, Clone)]
-pub struct InventoryPayloadDecoder(InventoryInnerDecoder);
+crate::decoder_newtype! {
+ /// Decoder type for [`InventoryPayload`].
+ #[derive(Debug, Default, Clone)]
+ pub struct InventoryPayloadDecoder(InventoryInnerDecoder);
-impl encoding::Decoder for InventoryPayloadDecoder {
- type Output = InventoryPayload;
- type Error = InventoryPayloadDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(InventoryPayloadDecoderError)
+ fn end(
+ result: Result<Vec<message_blockdata::Inventory>, <InventoryInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<InventoryPayload, InventoryPayloadDecoderError> {
+ Ok(InventoryPayload(result.map_err(InventoryPayloadDecoderError)?))
}
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- Ok(InventoryPayload(self.0.end().map_err(InventoryPayloadDecoderError)?))
- }
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for InventoryPayload {
@@ -383,26 +366,16 @@ impl encoding::Encode for AddrPayload {
type AddrPayloadInnerDecoder = VecDecoder<AddrV1Message>;
-/// Decoder type for [`AddrPayload`].
-#[derive(Debug, Default, Clone)]
-pub struct AddrPayloadDecoder(AddrPayloadInnerDecoder);
-
-impl encoding::Decoder for AddrPayloadDecoder {
- type Output = AddrPayload;
- type Error = AddrPayloadDecoderError;
+crate::decoder_newtype! {
+ /// Decoder type for [`AddrPayload`].
+ #[derive(Debug, Default, Clone)]
+ pub struct AddrPayloadDecoder(AddrPayloadInnerDecoder);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(AddrPayloadDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- Ok(AddrPayload(self.0.end().map_err(AddrPayloadDecoderError)?))
+ fn end(
+ result: Result<Vec<AddrV1Message>, <AddrPayloadInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<AddrPayload, AddrPayloadDecoderError> {
+ Ok(AddrPayload(result.map_err(AddrPayloadDecoderError)?))
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for AddrPayload {
@@ -435,26 +408,16 @@ impl encoding::Encode for AddrV2Payload {
type AddrV2PayloadInnerDecoder = VecDecoder<AddrV2Message>;
-/// Decoder type for [`AddrV2Payload`].
-#[derive(Debug, Default, Clone)]
-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<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(AddrV2PayloadDecoderError)
- }
+crate::decoder_newtype! {
+ /// Decoder type for [`AddrV2Payload`].
+ #[derive(Debug, Default, Clone)]
+ pub struct AddrV2PayloadDecoder(AddrV2PayloadInnerDecoder);
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- Ok(AddrV2Payload(self.0.end().map_err(AddrV2PayloadDecoderError)?))
+ fn end(
+ result: Result<Vec<AddrV2Message>, VecDecoderError<AddrV2MessageDecoderError>>
+ ) -> Result<AddrV2Payload, AddrV2PayloadDecoderError> {
+ Ok(AddrV2Payload(result.map_err(AddrV2PayloadDecoderError)?))
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for AddrV2Payload {
@@ -502,29 +465,22 @@ impl encoding::Encode for FeeFilter {
}
}
-/// Decoder for [`FeeFilter`] type.
-#[derive(Debug, Clone)]
-pub struct FeeFilterDecoder(encoding::ArrayDecoder<8>);
+crate::decoder_newtype! {
+ /// Decoder for [`FeeFilter`] type.
+ #[derive(Debug, Clone)]
+ pub struct FeeFilterDecoder(encoding::ArrayDecoder<8>);
-impl FeeFilterDecoder {
/// Constructs a new [`FeeFilter`] decoder.
pub fn new() -> Self { Self(encoding::ArrayDecoder::new()) }
-}
-
-impl Default for FeeFilterDecoder {
- fn default() -> Self { Self::new() }
-}
-
-impl encoding::Decoder for FeeFilterDecoder {
- type Output = FeeFilter;
- type Error = FeeFilterDecoderError;
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(FeeFilterDecoderError::UnexpectedEof)
+ fn map_push_bytes_err(err: encoding::UnexpectedEofError) -> FeeFilterDecoderError {
+ FeeFilterDecoderError::UnexpectedEof(err)
}
- fn end(self) -> Result<Self::Output, Self::Error> {
- let array = self.0.end().map_err(FeeFilterDecoderError::UnexpectedEof)?;
+ fn end(
+ result: Result<[u8; 8], encoding::UnexpectedEofError>
+ ) -> Result<FeeFilter, FeeFilterDecoderError> {
+ let array = result.map_err(FeeFilterDecoderError::UnexpectedEof)?;
let kvb = u64::from_le_bytes(array);
// BIP-0133 specifies feefilter as int64_t (signed), but negative values and values
@@ -543,8 +499,6 @@ impl encoding::Decoder for FeeFilterDecoder {
Ok(FeeFilter(fee_rate))
}
}
-
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for FeeFilter {
@@ -590,27 +544,15 @@ impl encoding::Encode for Ping {
}
}
-/// The Decoder for [`Ping`]
-#[derive(Debug, Default, Clone)]
-pub struct PingDecoder(encoding::ArrayDecoder<8>);
-
-impl encoding::Decoder for PingDecoder {
- type Output = Ping;
- type Error = PingDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(PingDecoderError)
- }
+crate::decoder_newtype! {
+ /// The Decoder for [`Ping`]
+ #[derive(Debug, Default, Clone)]
+ pub struct PingDecoder(encoding::ArrayDecoder<8>);
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let nonce = self.0.end().map_err(PingDecoderError)?;
+ fn end(result: Result<[u8; 8], encoding::UnexpectedEofError>) -> Result<Ping, PingDecoderError> {
+ let nonce = result.map_err(PingDecoderError)?;
Ok(Ping(u64::from_le_bytes(nonce)))
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for Ping {
@@ -646,27 +588,15 @@ impl encoding::Encode for Pong {
}
}
-/// The Decoder for [`Pong`]
-#[derive(Debug, Default, Clone)]
-pub struct PongDecoder(encoding::ArrayDecoder<8>);
-
-impl encoding::Decoder for PongDecoder {
- type Output = Pong;
- type Error = PongDecoderError;
+crate::decoder_newtype! {
+ /// The Decoder for [`Pong`]
+ #[derive(Debug, Default, Clone)]
+ pub struct PongDecoder(encoding::ArrayDecoder<8>);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, 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)?;
+ fn end(result: Result<[u8; 8], encoding::UnexpectedEofError>) -> Result<Pong, PongDecoderError> {
+ let nonce = result.map_err(PongDecoderError)?;
Ok(Pong(u64::from_le_bytes(nonce)))
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for Pong {
@@ -1654,27 +1584,17 @@ impl encoding::Encode for NetworkHeader {
type NetworkHeaderInnerDecoder = Decoder2<HeaderDecoder, ArrayDecoder<1>>;
-/// The decoder type for a [`NetworkHeader`].
-#[derive(Debug, Default, Clone)]
-pub struct NetworkHeaderDecoder(NetworkHeaderInnerDecoder);
-
-impl encoding::Decoder for NetworkHeaderDecoder {
- type Output = NetworkHeader;
- type Error = NetworkHeaderDecoderError;
+crate::decoder_newtype! {
+ /// The decoder type for a [`NetworkHeader`].
+ #[derive(Debug, Default, Clone)]
+ pub struct NetworkHeaderDecoder(NetworkHeaderInnerDecoder);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(NetworkHeaderDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (header, length) = self.0.end().map_err(NetworkHeaderDecoderError)?;
+ fn end(
+ result: Result<(Header, [u8; 1]), <NetworkHeaderInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<NetworkHeader, NetworkHeaderDecoderError> {
+ let (header, length) = result.map_err(NetworkHeaderDecoderError)?;
Ok(NetworkHeader { header, length: u8::from_le_bytes(length) })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for NetworkHeader {
@@ -1719,27 +1639,17 @@ impl encoding::Encode for HeadersMessage {
type HeadersMessageInnerDecoder = VecDecoder<NetworkHeader>;
-/// The decoder type for a [`HeadersMessage`].
-#[derive(Debug, Default, Clone)]
-pub struct HeadersMessageDecoder(HeadersMessageInnerDecoder);
-
-impl encoding::Decoder for HeadersMessageDecoder {
- type Output = HeadersMessage;
- type Error = HeadersMessageDecoderError;
+crate::decoder_newtype! {
+ /// The decoder type for a [`HeadersMessage`].
+ #[derive(Debug, Default, Clone)]
+ pub struct HeadersMessageDecoder(HeadersMessageInnerDecoder);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(HeadersMessageDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let headers = self.0.end().map_err(HeadersMessageDecoderError)?;
+ fn end(
+ result: Result<Vec<NetworkHeader>, <HeadersMessageInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<HeadersMessage, HeadersMessageDecoderError> {
+ let headers = result.map_err(HeadersMessageDecoderError)?;
Ok(HeadersMessage(headers))
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for HeadersMessage {
diff --git a/p2p/src/message_blockdata.rs b/p2p/src/message_blockdata.rs
index 267688cb..29a3814d 100644
--- a/p2p/src/message_blockdata.rs
+++ b/p2p/src/message_blockdata.rs
@@ -100,22 +100,15 @@ impl encoding::Encode for Inventory {
type InventoryInnerDecoder = Decoder2<ArrayDecoder<4>, ArrayDecoder<32>>;
-/// The decoder for the [`Inventory`] type.
-#[derive(Debug, Default, Clone)]
-pub struct InventoryDecoder(InventoryInnerDecoder);
-
-impl encoding::Decoder for InventoryDecoder {
- type Output = Inventory;
- type Error = InventoryDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(InventoryDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (ty, inv) = self.0.end().map_err(InventoryDecoderError)?;
+crate::decoder_newtype! {
+ /// The decoder for the [`Inventory`] type.
+ #[derive(Debug, Default, Clone)]
+ pub struct InventoryDecoder(InventoryInnerDecoder);
+
+ fn end(
+ result: Result<([u8; 4], [u8; 32]), <InventoryInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<Inventory, InventoryDecoderError> {
+ let (ty, inv) = result.map_err(InventoryDecoderError)?;
let inv_type = u32::from_le_bytes(ty);
Ok(match inv_type {
0 => Self::Output::Error(inv),
@@ -128,9 +121,6 @@ impl encoding::Decoder for InventoryDecoder {
tp => Self::Output::Unknown { inv_type: tp, hash: inv },
})
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for Inventory {
@@ -210,35 +200,19 @@ impl encoding::Encode for BlockLocator {
type BlockLocatorInnerDecoder = VecDecoder<BlockHash>;
-/// The decoder for the [`BlockLocator`] type.
-#[derive(Debug, Clone)]
-pub struct BlockLocatorDecoder(BlockLocatorInnerDecoder);
+crate::decoder_newtype! {
+ /// The decoder for the [`BlockLocator`] type.
+ #[derive(Debug, Clone)]
+ pub struct BlockLocatorDecoder(BlockLocatorInnerDecoder);
-impl BlockLocatorDecoder {
/// Creates a new decoder.
pub fn new() -> Self { Self(VecDecoder::<BlockHash>::new()) }
-}
-impl Default for BlockLocatorDecoder {
- fn default() -> Self { Self::new() }
-}
-
-impl encoding::Decoder for BlockLocatorDecoder {
- type Output = BlockLocator;
- type Error = BlockLocatorDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(BlockLocatorDecoderError)
+ fn end(
+ result: Result<Vec<BlockHash>, <BlockLocatorInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<BlockLocator, BlockLocatorDecoderError> {
+ result.map(BlockLocator).map_err(BlockLocatorDecoderError)
}
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- Ok(BlockLocator(self.0.end().map_err(BlockLocatorDecoderError)?))
- }
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for BlockLocator {
@@ -317,52 +291,32 @@ impl encoding::Encode for GetBlocksMessage {
type GetBlocksOrHeadersInnerDecoder =
Decoder3<ProtocolVersionDecoder, BlockLocatorDecoder, BlockHashDecoder>;
-/// Decoder type for [`GetBlocksMessage`].
-#[derive(Debug, Default, Clone)]
-pub struct GetBlocksMessageDecoder(GetBlocksOrHeadersInnerDecoder);
+crate::decoder_newtype! {
+ /// Decoder type for [`GetBlocksMessage`].
+ #[derive(Debug, Default, Clone)]
+ pub struct GetBlocksMessageDecoder(GetBlocksOrHeadersInnerDecoder);
-/// Decoder type for [`GetHeadersMessage`].
-#[derive(Debug, Default, Clone)]
-pub struct GetHeadersMessageDecoder(GetBlocksOrHeadersInnerDecoder);
-
-impl encoding::Decoder for GetHeadersMessageDecoder {
- type Output = GetHeadersMessage;
- type Error = GetHeadersMessageDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(GetHeadersMessageDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
+ fn end(
+ result: Result<(ProtocolVersion, BlockLocator, BlockHash), <GetBlocksOrHeadersInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<GetBlocksMessage, GetBlocksMessageDecoderError> {
let (version, locator_hashes, stop_hash) =
- self.0.end().map_err(GetHeadersMessageDecoderError)?;
- Ok(GetHeadersMessage { version, locator_hashes, stop_hash })
+ result.map_err(GetBlocksMessageDecoderError)?;
+ Ok(GetBlocksMessage { version, locator_hashes, stop_hash })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
-impl encoding::Decoder for GetBlocksMessageDecoder {
- type Output = GetBlocksMessage;
- type Error = GetBlocksMessageDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(GetBlocksMessageDecoderError)
- }
+crate::decoder_newtype! {
+ /// Decoder type for [`GetHeadersMessage`].
+ #[derive(Debug, Default, Clone)]
+ pub struct GetHeadersMessageDecoder(GetBlocksOrHeadersInnerDecoder);
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
+ fn end(
+ result: Result<(ProtocolVersion, BlockLocator, BlockHash), <GetBlocksOrHeadersInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<GetHeadersMessage, GetHeadersMessageDecoderError> {
let (version, locator_hashes, stop_hash) =
- self.0.end().map_err(GetBlocksMessageDecoderError)?;
- Ok(GetBlocksMessage { version, locator_hashes, stop_hash })
+ result.map_err(GetHeadersMessageDecoderError)?;
+ Ok(GetHeadersMessage { version, locator_hashes, stop_hash })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for GetBlocksMessage {
diff --git a/p2p/src/message_bloom.rs b/p2p/src/message_bloom.rs
index 3145604c..e2e08fd0 100644
--- a/p2p/src/message_bloom.rs
+++ b/p2p/src/message_bloom.rs
@@ -66,22 +66,18 @@ impl encoding::Encode for FilterLoad {
type FilterLoadInnerDecoder =
Decoder4<ByteVecDecoder, ArrayDecoder<4>, ArrayDecoder<4>, BloomFlagsDecoder>;
-/// The decoder for the [`FilterLoad`] message.
-#[derive(Debug, Default, Clone)]
-pub struct FilterLoadDecoder(FilterLoadInnerDecoder);
-
-impl encoding::Decoder for FilterLoadDecoder {
- type Output = FilterLoad;
- type Error = FilterLoadDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(FilterLoadDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (filter, hash_funcs, tweak, flags) = self.0.end().map_err(FilterLoadDecoderError)?;
+crate::decoder_newtype! {
+ /// The decoder for the [`FilterLoad`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct FilterLoadDecoder(FilterLoadInnerDecoder);
+
+ fn end(
+ result: Result<
+ <FilterLoadInnerDecoder as encoding::Decoder>::Output,
+ <FilterLoadInnerDecoder as encoding::Decoder>::Error,
+ >
+ ) -> Result<FilterLoad, FilterLoadDecoderError> {
+ let (filter, hash_funcs, tweak, flags) = result.map_err(FilterLoadDecoderError)?;
Ok(FilterLoad {
filter,
hash_funcs: u32::from_le_bytes(hash_funcs),
@@ -89,9 +85,6 @@ impl encoding::Decoder for FilterLoadDecoder {
flags,
})
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for FilterLoad {
@@ -129,30 +122,19 @@ impl encoding::Encode for BloomFlags {
type BloomFlagsInnerDecoder = ArrayDecoder<1>;
-/// The decoder for [`BloomFlags`].
-#[derive(Debug, Default, Clone)]
-pub struct BloomFlagsDecoder(BloomFlagsInnerDecoder);
+crate::decoder_newtype! {
+ /// The decoder for [`BloomFlags`].
+ #[derive(Debug, Default, Clone)]
+ pub struct BloomFlagsDecoder(BloomFlagsInnerDecoder);
-impl BloomFlagsDecoder {
- fn err_from_inner(
- inner: <ArrayDecoder<1> as encoding::Decoder>::Error,
- ) -> BloomFlagsDecoderError {
- BloomFlagsDecoderError::Decoder(inner)
+ fn map_push_bytes_err(err: encoding::UnexpectedEofError) -> BloomFlagsDecoderError {
+ BloomFlagsDecoderError::Decoder(err)
}
-}
-
-impl encoding::Decoder for BloomFlagsDecoder {
- type Output = BloomFlags;
- type Error = BloomFlagsDecoderError;
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(Self::err_from_inner)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let bloom_flag_arr = self.0.end().map_err(Self::err_from_inner)?;
+ fn end(
+ result: Result<[u8; 1], encoding::UnexpectedEofError>
+ ) -> Result<BloomFlags, BloomFlagsDecoderError> {
+ let bloom_flag_arr = result.map_err(BloomFlagsDecoderError::Decoder)?;
let bloom_flag = u8::from_le_bytes(bloom_flag_arr);
Ok(match bloom_flag {
0 => BloomFlags::None,
@@ -161,9 +143,6 @@ impl encoding::Decoder for BloomFlagsDecoder {
flag => return Err(BloomFlagsDecoderError::UnknownFlag(flag)),
})
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for BloomFlags {
@@ -196,27 +175,17 @@ impl encoding::Encode for FilterAdd {
type FilterAddInnerDecoder = ByteVecDecoder;
-/// The decoder for the [`FilterAdd`] message.
-#[derive(Debug, Default, Clone)]
-pub struct FilterAddDecoder(FilterAddInnerDecoder);
-
-impl encoding::Decoder for FilterAddDecoder {
- type Output = FilterAdd;
- type Error = FilterAddDecoderError;
+crate::decoder_newtype! {
+ /// The decoder for the [`FilterAdd`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct FilterAddDecoder(FilterAddInnerDecoder);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(FilterAddDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let data = self.0.end().map_err(FilterAddDecoderError)?;
+ fn end(
+ result: Result<Vec<u8>, encoding::ByteVecDecoderError>
+ ) -> Result<FilterAdd, FilterAddDecoderError> {
+ let data = result.map_err(FilterAddDecoderError)?;
Ok(FilterAdd { data })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for FilterAdd {
diff --git a/p2p/src/message_compact_blocks.rs b/p2p/src/message_compact_blocks.rs
index 1bc4ccde..2a14da8e 100644
--- a/p2p/src/message_compact_blocks.rs
+++ b/p2p/src/message_compact_blocks.rs
@@ -39,28 +39,18 @@ impl encoding::Encode for SendCmpct {
type SendCmpctInnerDecoder = Decoder2<ArrayDecoder<1>, ArrayDecoder<8>>;
-/// Decoder type for the [`SendCmpct`] message.
-#[derive(Debug, Default, Clone)]
-pub struct SendCmpctDecoder(SendCmpctInnerDecoder);
-
-impl encoding::Decoder for SendCmpctDecoder {
- type Output = SendCmpct;
- type Error = SendCmpctDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(SendCmpctDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (send_cmpct, version) = self.0.end().map_err(SendCmpctDecoderError)?;
+crate::decoder_newtype! {
+ /// Decoder type for the [`SendCmpct`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct SendCmpctDecoder(SendCmpctInnerDecoder);
+
+ fn end(
+ result: Result<([u8; 1], [u8; 8]), <SendCmpctInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<SendCmpct, SendCmpctDecoderError> {
+ let (send_cmpct, version) = result.map_err(SendCmpctDecoderError)?;
let send_compact = u8::from_le_bytes(send_cmpct) != 0;
Ok(SendCmpct { send_compact, version: u64::from_le_bytes(version) })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for SendCmpct {
diff --git a/p2p/src/message_erlay.rs b/p2p/src/message_erlay.rs
index de53691f..3d4c47ae 100644
--- a/p2p/src/message_erlay.rs
+++ b/p2p/src/message_erlay.rs
@@ -55,29 +55,15 @@ impl encoding::Encode for SendTxRcnCl {
type SendTxRcnClInnerDecoder = Decoder2<ArrayDecoder<4>, ArrayDecoder<8>>;
-/// The decoder for a [`SendTxRcnCl`] message.
-#[derive(Debug, Default, Clone)]
-pub struct SendTxRcnClDecoder(SendTxRcnClInnerDecoder);
+crate::decoder_newtype! {
+ /// The decoder for a [`SendTxRcnCl`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct SendTxRcnClDecoder(SendTxRcnClInnerDecoder);
-impl encoding::Decoder for SendTxRcnClDecoder {
- type Output = SendTxRcnCl;
- type Error = SendTxRcnClDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(SendTxRcnClDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (version, salt) = self.0.end().map_err(SendTxRcnClDecoderError)?;
+ fn end(result: Result<([u8; 4], [u8; 8]), <SendTxRcnClInnerDecoder as encoding::Decoder>::Error>) -> Result<SendTxRcnCl, SendTxRcnClDecoderError> {
+ let (version, salt) = result.map_err(SendTxRcnClDecoderError)?;
Ok(SendTxRcnCl { version: u32::from_le_bytes(version), salt: u64::from_le_bytes(salt) })
}
-
- #[inline]
- fn read_limit(&self) -> usize {
- self.0.read_limit()
- }
}
impl encoding::Decode for SendTxRcnCl {
diff --git a/p2p/src/message_filter.rs b/p2p/src/message_filter.rs
index b7281e20..18bac30e 100644
--- a/p2p/src/message_filter.rs
+++ b/p2p/src/message_filter.rs
@@ -77,54 +77,34 @@ impl encoding::Encode for FilterHeader {
type HashInnerDecoder = ArrayDecoder<32>;
-/// Decoder for the [`FilterHash`] type.
-#[derive(Debug, Default, Clone)]
-pub struct FilterHashDecoder(HashInnerDecoder);
-
-impl encoding::Decoder for FilterHashDecoder {
- type Output = FilterHash;
- type Error = FilterHashDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(FilterHashDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let arr = self.0.end().map_err(FilterHashDecoderError)?;
+crate::decoder_newtype! {
+ /// Decoder for the [`FilterHash`] type.
+ #[derive(Debug, Default, Clone)]
+ pub struct FilterHashDecoder(HashInnerDecoder);
+
+ fn end(
+ result: Result<[u8; 32], encoding::UnexpectedEofError>
+ ) -> Result<FilterHash, FilterHashDecoderError> {
+ let arr = result.map_err(FilterHashDecoderError)?;
Ok(FilterHash::from_byte_array(arr))
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for FilterHash {
type Decoder = FilterHashDecoder;
}
-/// Decoder for the [`FilterHeader`] type.
-#[derive(Debug, Default, Clone)]
-pub struct FilterHeaderDecoder(HashInnerDecoder);
+crate::decoder_newtype! {
+ /// Decoder for the [`FilterHeader`] type.
+ #[derive(Debug, Default, Clone)]
+ pub struct FilterHeaderDecoder(HashInnerDecoder);
-impl encoding::Decoder for FilterHeaderDecoder {
- type Output = FilterHeader;
- type Error = FilterHeaderDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(FilterHeaderDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let arr = self.0.end().map_err(FilterHeaderDecoderError)?;
+ fn end(
+ result: Result<[u8; 32], encoding::UnexpectedEofError>
+ ) -> Result<FilterHeader, FilterHeaderDecoderError> {
+ let arr = result.map_err(FilterHeaderDecoderError)?;
Ok(FilterHeader::from_byte_array(arr))
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for FilterHeader {
@@ -176,27 +156,17 @@ impl encoding::Encode for GetCFilters {
type GetCFiltersInnerDecoder = Decoder3<ArrayDecoder<1>, BlockHeightDecoder, BlockHashDecoder>;
-/// Decoder type for the [`GetCFilters`] message.
-#[derive(Debug, Default, Clone)]
-pub struct GetCFiltersDecoder(GetCFiltersInnerDecoder);
+crate::decoder_newtype! {
+ /// Decoder type for the [`GetCFilters`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct GetCFiltersDecoder(GetCFiltersInnerDecoder);
-impl encoding::Decoder for GetCFiltersDecoder {
- type Output = GetCFilters;
- type Error = GetCFiltersDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(GetCFiltersDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (ty, start_height, stop_hash) = self.0.end().map_err(GetCFiltersDecoderError)?;
+ fn end(
+ result: Result<([u8; 1], BlockHeight, BlockHash), <GetCFiltersInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<GetCFilters, GetCFiltersDecoderError> {
+ let (ty, start_height, stop_hash) = result.map_err(GetCFiltersDecoderError)?;
Ok(GetCFilters { filter_type: u8::from_le_bytes(ty), start_height, stop_hash })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for GetCFilters {
@@ -246,27 +216,17 @@ impl encoding::Encode for CFilter {
type CFilterInnerDecoder = Decoder3<ArrayDecoder<1>, BlockHashDecoder, ByteVecDecoder>;
-/// Decoder type for a [`CFilter`] message.
-#[derive(Debug, Default, Clone)]
-pub struct CFilterDecoder(CFilterInnerDecoder);
+crate::decoder_newtype! {
+ /// Decoder type for a [`CFilter`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct CFilterDecoder(CFilterInnerDecoder);
-impl encoding::Decoder for CFilterDecoder {
- type Output = CFilter;
- type Error = CFilterDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(CFilterDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (ty, block_hash, filter) = self.0.end().map_err(CFilterDecoderError)?;
+ fn end(
+ result: Result<([u8; 1], BlockHash, Vec<u8>), <CFilterInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<CFilter, CFilterDecoderError> {
+ let (ty, block_hash, filter) = result.map_err(CFilterDecoderError)?;
Ok(CFilter { filter_type: u8::from_le_bytes(ty), block_hash, filter })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for CFilter {
@@ -304,27 +264,17 @@ impl encoding::Encode for GetCFHeaders {
type GetCFHeadersInnerDecoder = Decoder3<ArrayDecoder<1>, BlockHeightDecoder, BlockHashDecoder>;
-/// Decoder type for the [`GetCFHeaders`] message.
-#[derive(Debug, Default, Clone)]
-pub struct GetCFHeadersDecoder(GetCFHeadersInnerDecoder);
+crate::decoder_newtype! {
+ /// Decoder type for the [`GetCFHeaders`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct GetCFHeadersDecoder(GetCFHeadersInnerDecoder);
-impl encoding::Decoder for GetCFHeadersDecoder {
- type Output = GetCFHeaders;
- type Error = GetCFHeadersDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(GetCFHeadersDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (ty, start_height, stop_hash) = self.0.end().map_err(GetCFHeadersDecoderError)?;
+ fn end(
+ result: Result<([u8; 1], BlockHeight, BlockHash), <GetCFHeadersInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<GetCFHeaders, GetCFHeadersDecoderError> {
+ let (ty, start_height, stop_hash) = result.map_err(GetCFHeadersDecoderError)?;
Ok(GetCFHeaders { filter_type: u8::from_le_bytes(ty), start_height, stop_hash })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for GetCFHeaders {
@@ -376,23 +326,19 @@ impl encoding::Encode for CFHeaders {
type CFHeadersInnerDecoder =
Decoder4<ArrayDecoder<1>, BlockHashDecoder, FilterHeaderDecoder, VecDecoder<FilterHash>>;
-/// Decoder type for a [`CFHeaders`] message.
-#[derive(Debug, Default, Clone)]
-pub struct CFHeadersDecoder(CFHeadersInnerDecoder);
-
-impl encoding::Decoder for CFHeadersDecoder {
- type Output = CFHeaders;
- type Error = CFHeadersDecoderError;
+crate::decoder_newtype! {
+ /// Decoder type for a [`CFHeaders`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct CFHeadersDecoder(CFHeadersInnerDecoder);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(CFHeadersDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
+ fn end(
+ result: Result<
+ <CFHeadersInnerDecoder as encoding::Decoder>::Output,
+ <CFHeadersInnerDecoder as encoding::Decoder>::Error,
+ >
+ ) -> Result<CFHeaders, CFHeadersDecoderError> {
let (ty, stop_hash, previous_filter_header, filter_hashes) =
- self.0.end().map_err(CFHeadersDecoderError)?;
+ result.map_err(CFHeadersDecoderError)?;
Ok(CFHeaders {
filter_type: u8::from_le_bytes(ty),
stop_hash,
@@ -400,9 +346,6 @@ impl encoding::Decoder for CFHeadersDecoder {
filter_hashes,
})
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for CFHeaders {
@@ -437,27 +380,17 @@ impl encoding::Encode for GetCFCheckpt {
type GetCFCheckptInnerDecoder = Decoder2<ArrayDecoder<1>, BlockHashDecoder>;
-/// Decoder type for a [`GetCFCheckpt`] message.
-#[derive(Debug, Default, Clone)]
-pub struct GetCFCheckptDecoder(GetCFCheckptInnerDecoder);
+crate::decoder_newtype! {
+ /// Decoder type for a [`GetCFCheckpt`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct GetCFCheckptDecoder(GetCFCheckptInnerDecoder);
-impl encoding::Decoder for GetCFCheckptDecoder {
- type Output = GetCFCheckpt;
- type Error = GetCFCheckptDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(GetCFCheckptDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (ty, stop_hash) = self.0.end().map_err(GetCFCheckptDecoderError)?;
+ fn end(
+ result: Result<([u8; 1], BlockHash), <GetCFCheckptInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<GetCFCheckpt, GetCFCheckptDecoderError> {
+ let (ty, stop_hash) = result.map_err(GetCFCheckptDecoderError)?;
Ok(GetCFCheckpt { filter_type: u8::from_le_bytes(ty), stop_hash })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for GetCFCheckpt {
@@ -507,27 +440,17 @@ impl encoding::Encode for CFCheckpt {
type CFCheckptInnerDecoder = Decoder3<ArrayDecoder<1>, BlockHashDecoder, VecDecoder<FilterHeader>>;
-/// Decoder type for a [`CFCheckpt`] message.
-#[derive(Debug, Default, Clone)]
-pub struct CFCheckptDecoder(CFCheckptInnerDecoder);
+crate::decoder_newtype! {
+ /// Decoder type for a [`CFCheckpt`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct CFCheckptDecoder(CFCheckptInnerDecoder);
-impl encoding::Decoder for CFCheckptDecoder {
- type Output = CFCheckpt;
- type Error = CFCheckptDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(CFCheckptDecoderError)
- }
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (ty, stop_hash, filter_headers) = self.0.end().map_err(CFCheckptDecoderError)?;
+ fn end(
+ result: Result<([u8; 1], BlockHash, Vec<FilterHeader>), <CFCheckptInnerDecoder as encoding::Decoder>::Error>
+ ) -> Result<CFCheckpt, CFCheckptDecoderError> {
+ let (ty, stop_hash, filter_headers) = result.map_err(CFCheckptDecoderError)?;
Ok(CFCheckpt { filter_type: u8::from_le_bytes(ty), stop_hash, filter_headers })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for CFCheckpt {
diff --git a/p2p/src/message_network.rs b/p2p/src/message_network.rs
index 5d243fbc..a2816203 100644
--- a/p2p/src/message_network.rs
+++ b/p2p/src/message_network.rs
@@ -141,22 +141,37 @@ impl encoding::Decode for VersionMessage {
type Decoder = VersionMessageDecoder;
}
-impl encoding::Decoder for VersionMessageDecoder {
- type Output = VersionMessage;
- type Error = VersionMessageDecoderError;
+type VersionMessageInnerDecoder = encoding::Decoder2<
+ encoding::Decoder3<
+ crate::ProtocolVersionDecoder,
+ crate::ServiceFlagsDecoder,
+ encoding::ArrayDecoder<8>,
+ >,
+ encoding::Decoder6<
+ AddressDecoder,
+ AddressDecoder,
+ encoding::ArrayDecoder<8>,
+ UserAgentDecoder,
+ encoding::ArrayDecoder<4>,
+ encoding::ArrayDecoder<1>,
+ >,
+>;
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(VersionMessageDecoderError)
- }
+crate::decoder_newtype! {
+ /// The Decoder for [`VersionMessage`].
+ #[derive(Debug, Default, Clone)]
+ pub struct VersionMessageDecoder(VersionMessageInnerDecoder);
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
+ fn end(
+ result: Result<
+ <VersionMessageInnerDecoder as encoding::Decoder>::Output,
+ <VersionMessageInnerDecoder as encoding::Decoder>::Error,
+ >
+ ) -> Result<VersionMessage, VersionMessageDecoderError> {
let (
(version, services, timestamp),
(receiver, sender, nonce, user_agent, start_height, relay),
- ) = self.0.end().map_err(VersionMessageDecoderError)?;
-
+ ) = result.map_err(VersionMessageDecoderError)?;
Ok(VersionMessage {
version,
services,
@@ -169,31 +184,8 @@ impl encoding::Decoder for VersionMessageDecoder {
relay: relay[0] != 0,
})
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
-type VersionMessageInnerDecoder = encoding::Decoder2<
- encoding::Decoder3<
- crate::ProtocolVersionDecoder,
- crate::ServiceFlagsDecoder,
- encoding::ArrayDecoder<8>,
- >,
- encoding::Decoder6<
- AddressDecoder,
- AddressDecoder,
- encoding::ArrayDecoder<8>,
- UserAgentDecoder,
- encoding::ArrayDecoder<4>,
- encoding::ArrayDecoder<1>,
- >,
->;
-
-/// The Decoder for [`VersionMessage`].
-#[derive(Debug, Default, Clone)]
-pub struct VersionMessageDecoder(VersionMessageInnerDecoder);
-
/// A bitcoin user agent defined by BIP-0014. The user agent is sent in the version message when a
/// connection between two peers is established. It is intended to advertise client software in a
/// well-defined format.
@@ -223,29 +215,23 @@ impl encoding::Encode for UserAgent {
type UserAgentInnerDecoder = ByteVecDecoder;
-/// The decoder for the [`UserAgent`] message.
-#[derive(Debug, Default, Clone)]
-pub struct UserAgentDecoder(UserAgentInnerDecoder);
+crate::decoder_newtype! {
+ /// The decoder for the [`UserAgent`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct UserAgentDecoder(UserAgentInnerDecoder);
-impl encoding::Decoder for UserAgentDecoder {
- type Output = UserAgent;
- type Error = UserAgentDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(UserAgentDecoderError::Decoder)
+ fn map_push_bytes_err(err: encoding::ByteVecDecoderError) -> UserAgentDecoderError {
+ UserAgentDecoderError::Decoder(err)
}
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let bytes = self.0.end().map_err(UserAgentDecoderError::Decoder)?;
+ fn end(
+ result: Result<Vec<u8>, encoding::ByteVecDecoderError>
+ ) -> Result<UserAgent, UserAgentDecoderError> {
+ let bytes = result.map_err(UserAgentDecoderError::Decoder)?;
let user_agent =
String::from_utf8(bytes).map_err(|_| UserAgentDecoderError::InvalidUtf8)?;
Ok(UserAgent { user_agent })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for UserAgent {
@@ -432,22 +418,19 @@ impl encoding::Encode for RejectReason {
}
}
-/// The decoder type for a [`RejectReason`].
-#[derive(Debug, Default, Clone)]
-pub struct RejectReasonDecoder(ArrayDecoder<1>);
-
-impl encoding::Decoder for RejectReasonDecoder {
- type Output = RejectReason;
- type Error = RejectReasonDecoderError;
+crate::decoder_newtype! {
+ /// The decoder type for a [`RejectReason`].
+ #[derive(Debug, Default, Clone)]
+ pub struct RejectReasonDecoder(ArrayDecoder<1>);
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(RejectReasonDecoderError::Decoder)
+ fn map_push_bytes_err(err: encoding::UnexpectedEofError) -> RejectReasonDecoderError {
+ RejectReasonDecoderError::Decoder(err)
}
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let code_arr = self.0.end().map_err(RejectReasonDecoderError::Decoder)?;
+ fn end(
+ result: Result<[u8; 1], encoding::UnexpectedEofError>
+ ) -> Result<RejectReason, RejectReasonDecoderError> {
+ let code_arr = result.map_err(RejectReasonDecoderError::Decoder)?;
let code = u8::from_le_bytes(code_arr);
Ok(match code {
0x01 => RejectReason::Malformed,
@@ -461,9 +444,6 @@ impl encoding::Decoder for RejectReasonDecoder {
unknown => return Err(RejectReasonDecoderError::UnknownRejectCode(unknown)),
})
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for RejectReason {
@@ -520,22 +500,22 @@ impl encoding::Encode for Reject {
type RejectInnerDecoder =
Decoder4<ByteVecDecoder, RejectReasonDecoder, ByteVecDecoder, ArrayDecoder<32>>;
-/// The decoder type for a [`Reject`] message.
-#[derive(Debug, Default, Clone)]
-pub struct RejectDecoder(RejectInnerDecoder);
+crate::decoder_newtype! {
+ /// The decoder type for a [`Reject`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct RejectDecoder(RejectInnerDecoder);
-impl encoding::Decoder for RejectDecoder {
- type Output = Reject;
- type Error = RejectDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(RejectDecoderError::Decoder)
+ fn map_push_bytes_err(err: <RejectInnerDecoder as encoding::Decoder>::Error) -> RejectDecoderError {
+ RejectDecoderError::Decoder(err)
}
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- let (message, ccode, reason, hash) = self.0.end().map_err(RejectDecoderError::Decoder)?;
+ fn end(
+ result: Result<
+ <RejectInnerDecoder as encoding::Decoder>::Output,
+ <RejectInnerDecoder as encoding::Decoder>::Error,
+ >
+ ) -> Result<Reject, RejectDecoderError> {
+ let (message, ccode, reason, hash) = result.map_err(RejectDecoderError::Decoder)?;
let message = String::from_utf8(message)
.map_err(|_| RejectDecoderError::InvalidUtf8)
.map(Cow::Owned)?;
@@ -545,9 +525,6 @@ impl encoding::Decoder for RejectDecoder {
let hash = sha256d::Hash::from_byte_array(hash);
Ok(Reject { message, ccode, reason, hash })
}
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for Reject {
@@ -605,26 +582,16 @@ impl encoding::Encode for Alert {
type AlertInnerDecoder = ByteVecDecoder;
-/// The decoder for the [`Alert`] message.
-#[derive(Debug, Default, Clone)]
-pub struct AlertDecoder(AlertInnerDecoder);
+crate::decoder_newtype! {
+ /// The decoder for the [`Alert`] message.
+ #[derive(Debug, Default, Clone)]
+ pub struct AlertDecoder(AlertInnerDecoder);
-impl encoding::Decoder for AlertDecoder {
- type Output = Alert;
- type Error = AlertDecoderError;
-
- #[inline]
- fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<encoding::DecoderStatus, Self::Error> {
- self.0.push_bytes(bytes).map_err(AlertDecoderError)
+ fn end(
+ result: Result<Vec<u8>, encoding::ByteVecDecoderError>
+ ) -> Result<Alert, AlertDecoderError> {
+ Ok(Alert(result.map_err(AlertDecoderError)?))
}
-
- #[inline]
- fn end(self) -> Result<Self::Output, Self::Error> {
- Ok(Alert(self.0.end().map_err(AlertDecoderError)?))
- }
-
- #[inline]
- fn read_limit(&self) -> usize { self.0.read_limit() }
}
impl encoding::Decode for Alert {
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.