What changed, and why it matters
This commit is a Rust type-system cleanup. It changes a macro that creates encoder wrapper types so that every wrapper must carry a lifetime parameter, and updates all uses across the codebase. There is no change to runtime behavior, wire format, or cryptographic logic. It prevents future misuse of the macro but does not fix a known exploitable bug.
No security action required. Treat as normal refactoring/quality improvement. If auditing, verify that the lifetime changes compile and that no public API stability guarantees are broken unexpectedly.
Security signals we found
No runtime behavior change
No input parsing changes
No cryptographic operations modified
Macro lifetime enforcement is defensive API design, not a vulnerability fix
No mention of security, CVE, bug, or disclosure in commit message
Evidence from the diff
The encoder_newtype! and encoder_newtype_exact! macros previously allowed defining encoder newtypes without a lifetime. The patch makes the lifetime mandatory, stores a PhantomData<&'e T> marker, and adds a new constructor. All call sites are updated to declare <'e> and use EncoderName::new(...). This is a compile-time API refactor inside the new consensus_encoding crate and its consumers (p2p, primitives, units). It does not alter encoding output or parsing.
Changed components
consensus_encoding macro definitionsp2p message encodersprimitives block/transaction encodersunits encodersInspect captured patch +179 / −158
diff --git a/consensus_encoding/examples/encoder.rs b/consensus_encoding/examples/encoder.rs
index 30453b6a..d08c8fce 100644
--- a/consensus_encoding/examples/encoder.rs
+++ b/consensus_encoding/examples/encoder.rs
@@ -45,7 +45,7 @@ impl Encodable for Adt {
);
let b = BytesEncoder::without_length_prefix(self.b.as_ref());
- AdtEncoder(Encoder2::new(a, b))
+ AdtEncoder::new(Encoder2::new(a, b))
}
}
@@ -63,12 +63,12 @@ impl Inner {
encoding::encoder_newtype_exact! {
/// The encoder for the [`Inner`] type.
- pub struct InnerEncoder(ArrayEncoder<4>);
+ pub struct InnerEncoder<'e>(ArrayEncoder<4>);
}
impl Encodable for Inner {
- type Encoder<'e> = InnerEncoder;
+ type Encoder<'e> = InnerEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- InnerEncoder(ArrayEncoder::without_length_prefix(self.to_array()))
+ InnerEncoder::new(ArrayEncoder::without_length_prefix(self.to_array()))
}
}
diff --git a/consensus_encoding/src/encode/mod.rs b/consensus_encoding/src/encode/mod.rs
index 230b6ebd..5dcf21f4 100644
--- a/consensus_encoding/src/encode/mod.rs
+++ b/consensus_encoding/src/encode/mod.rs
@@ -49,12 +49,19 @@ pub trait Encoder {
macro_rules! encoder_newtype{
(
$(#[$($struct_attr:tt)*])*
- pub struct $name:ident$(<$lt:lifetime>)?($encoder:ty);
+ pub struct $name:ident<$lt:lifetime>($encoder:ty);
) => {
$(#[$($struct_attr)*])*
- pub struct $name$(<$lt>)?($encoder);
+ pub struct $name<$lt>($encoder, core::marker::PhantomData<&$lt $encoder>);
- impl$(<$lt>)? $crate::Encoder for $name$(<$lt>)? {
+ impl<$lt> $name<$lt> {
+ /// Construct a new instance of the newtype encoder
+ pub fn new(encoder: $encoder) -> $name<$lt> {
+ $name(encoder, core::marker::PhantomData)
+ }
+ }
+
+ impl<$lt> $crate::Encoder for $name<$lt> {
#[inline]
fn current_chunk(&self) -> &[u8] { self.0.current_chunk() }
@@ -71,14 +78,14 @@ macro_rules! encoder_newtype{
macro_rules! encoder_newtype_exact{
(
$(#[$($struct_attr:tt)*])*
- pub struct $name:ident$(<$lt:lifetime>)?($encoder:ty);
+ pub struct $name:ident<$lt:lifetime>($encoder:ty);
) => {
$crate::encoder_newtype! {
$(#[$($struct_attr)*])*
- pub struct $name$(<$lt>)?($encoder);
+ pub struct $name<$lt>($encoder);
}
- impl$(<$lt>)? $crate::ExactSizeEncoder for $name$(<$lt>)? {
+ impl<$lt> $crate::ExactSizeEncoder for $name<$lt> {
#[inline]
fn len(&self) -> usize { self.0.len() }
}
diff --git a/consensus_encoding/tests/encode.rs b/consensus_encoding/tests/encode.rs
index f86b63ba..973af908 100644
--- a/consensus_encoding/tests/encode.rs
+++ b/consensus_encoding/tests/encode.rs
@@ -111,12 +111,12 @@ fn encode_newtype_lifetime_flexibility() {
pub struct CustomEncoder<'data>(BytesEncoder<'data>);
}
bitcoin_consensus_encoding::encoder_newtype! {
- pub struct NoLifetimeEncoder(ArrayEncoder<4>);
+ pub struct NoLifetimeEncoder<'e>(ArrayEncoder<4>);
}
let test_data = b"hello world";
- let custom_encoder = CustomEncoder(BytesEncoder::without_length_prefix(test_data));
- let no_lifetime_encoder = NoLifetimeEncoder(ArrayEncoder::without_length_prefix([1, 2, 3, 4]));
+ let custom_encoder = CustomEncoder::new(BytesEncoder::without_length_prefix(test_data));
+ let no_lifetime_encoder = NoLifetimeEncoder::new(ArrayEncoder::without_length_prefix([1, 2, 3, 4]));
assert_eq!(custom_encoder.current_chunk(), test_data.as_slice());
assert_eq!(no_lifetime_encoder.current_chunk(), &[1, 2, 3, 4][..]);
diff --git a/consensus_encoding/tests/wrappers.rs b/consensus_encoding/tests/wrappers.rs
index 3884d1c2..8c08a037 100644
--- a/consensus_encoding/tests/wrappers.rs
+++ b/consensus_encoding/tests/wrappers.rs
@@ -7,7 +7,7 @@ use encoding::{ArrayEncoder, BytesEncoder, CompactSizeEncoder, Encodable, Encode
encoding::encoder_newtype_exact! {
/// An encoder that uses an inner `ArrayEncoder`.
- pub struct TestArrayEncoder(ArrayEncoder<4>);
+ pub struct TestArrayEncoder<'e>(ArrayEncoder<4>);
}
encoding::encoder_newtype_exact! {
@@ -21,9 +21,9 @@ fn array_encoder() {
pub struct Test(u32);
impl Encodable for Test {
- type Encoder<'e> = TestArrayEncoder;
+ type Encoder<'e> = TestArrayEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- TestArrayEncoder(ArrayEncoder::without_length_prefix(self.0.to_le_bytes()))
+ TestArrayEncoder::new(ArrayEncoder::without_length_prefix(self.0.to_le_bytes()))
}
}
@@ -47,7 +47,7 @@ fn bytes_encoder_without_length_prefix() {
Self: 'e;
fn encoder(&self) -> Self::Encoder<'_> {
- TestBytesEncoder(BytesEncoder::without_length_prefix(self.0.as_ref()))
+ TestBytesEncoder::new(BytesEncoder::without_length_prefix(self.0.as_ref()))
}
}
@@ -71,8 +71,8 @@ fn two_encoder() {
type Encoder<'e> = Encoder2<TestBytesEncoder<'e>, TestBytesEncoder<'e>>;
fn encoder(&self) -> Self::Encoder<'_> {
- let a = TestBytesEncoder(BytesEncoder::without_length_prefix(self.a.as_ref()));
- let b = TestBytesEncoder(BytesEncoder::without_length_prefix(self.b.as_ref()));
+ let a = TestBytesEncoder::new(BytesEncoder::without_length_prefix(self.a.as_ref()));
+ let b = TestBytesEncoder::new(BytesEncoder::without_length_prefix(self.b.as_ref()));
Encoder2::new(a, b)
}
@@ -103,7 +103,7 @@ fn slice_encoder() {
Self: 'a;
fn encoder(&self) -> Self::Encoder<'_> {
- TestEncoder(Encoder2::new(
+ TestEncoder::new(Encoder2::new(
CompactSizeEncoder::new(self.0.len()),
SliceEncoder::without_length_prefix(&self.0),
))
@@ -115,14 +115,14 @@ fn slice_encoder() {
encoding::encoder_newtype_exact! {
/// The encoder for the [`Inner`] type.
- pub struct InnerArrayEncoder(ArrayEncoder<4>);
+ pub struct InnerArrayEncoder<'e>(ArrayEncoder<4>);
}
impl Encodable for Inner {
- type Encoder<'e> = InnerArrayEncoder;
+ type Encoder<'e> = InnerArrayEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
// Big-endian to make reading the test assertion easier.
- InnerArrayEncoder(ArrayEncoder::without_length_prefix(self.0.to_be_bytes()))
+ InnerArrayEncoder::new(ArrayEncoder::without_length_prefix(self.0.to_be_bytes()))
}
}
diff --git a/p2p/src/bip152.rs b/p2p/src/bip152.rs
index b5e94348..a8431372 100644
--- a/p2p/src/bip152.rs
+++ b/p2p/src/bip152.rs
@@ -415,7 +415,7 @@ encoding::encoder_newtype! {
/// The encoder for [`BlockTransactionsRequest`].
pub struct BlockTransactionsRequestEncoder<'e>(
Encoder2<
- BlockHashEncoder,
+ BlockHashEncoder<'e>,
Encoder2<CompactSizeEncoder, SliceEncoder<'e, Offset>>
>
);
@@ -425,13 +425,15 @@ impl encoding::Encodable for BlockTransactionsRequest {
type Encoder<'e> = BlockTransactionsRequestEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- BlockTransactionsRequestEncoder(Encoder2::new(
- self.block_hash.encoder(),
+ BlockTransactionsRequestEncoder::new(
Encoder2::new(
- CompactSizeEncoder::new(self.offsets.len()),
- SliceEncoder::without_length_prefix(&self.offsets),
- ),
- ))
+ self.block_hash.encoder(),
+ Encoder2::new(
+ CompactSizeEncoder::new(self.offsets.len()),
+ SliceEncoder::without_length_prefix(&self.offsets),
+ ),
+ )
+ )
}
}
diff --git a/p2p/src/lib.rs b/p2p/src/lib.rs
index edc3519c..9ee838d2 100644
--- a/p2p/src/lib.rs
+++ b/p2p/src/lib.rs
@@ -113,13 +113,15 @@ impl Decodable for ProtocolVersion {
encoding::encoder_newtype! {
/// The encoder for the [`ProtocolVersion`] type.
- pub struct ProtocolVersionEncoder(encoding::ArrayEncoder<4>);
+ pub struct ProtocolVersionEncoder<'e>(encoding::ArrayEncoder<4>);
}
impl encoding::Encodable for ProtocolVersion {
- type Encoder<'e> = ProtocolVersionEncoder;
+ type Encoder<'e> = ProtocolVersionEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- ProtocolVersionEncoder(encoding::ArrayEncoder::without_length_prefix(self.0.to_le_bytes()))
+ ProtocolVersionEncoder::new(encoding::ArrayEncoder::without_length_prefix(
+ self.0.to_le_bytes(),
+ ))
}
}
@@ -336,13 +338,15 @@ impl Decodable for ServiceFlags {
encoding::encoder_newtype! {
/// The encoder for the [`ServiceFlags`] type.
- pub struct ServiceFlagsEncoder(encoding::ArrayEncoder<8>);
+ pub struct ServiceFlagsEncoder<'e>(encoding::ArrayEncoder<8>);
}
impl encoding::Encodable for ServiceFlags {
- type Encoder<'e> = ServiceFlagsEncoder;
+ type Encoder<'e> = ServiceFlagsEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- ServiceFlagsEncoder(encoding::ArrayEncoder::without_length_prefix(self.0.to_le_bytes()))
+ ServiceFlagsEncoder::new(encoding::ArrayEncoder::without_length_prefix(
+ self.0.to_le_bytes(),
+ ))
}
}
diff --git a/p2p/src/message.rs b/p2p/src/message.rs
index 39c81ba7..dd91bc57 100644
--- a/p2p/src/message.rs
+++ b/p2p/src/message.rs
@@ -405,16 +405,16 @@ impl bitcoin::consensus::encode::Decodable for FeeFilter {
encoding::encoder_newtype_exact! {
/// Encoder for [`FeeFilter`] type.
- pub struct FeeFilterEncoder(encoding::ArrayEncoder<8>);
+ pub struct FeeFilterEncoder<'e>(encoding::ArrayEncoder<8>);
}
impl encoding::Encodable for FeeFilter {
- type Encoder<'e> = FeeFilterEncoder;
+ type Encoder<'e> = FeeFilterEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
// Encode as sat/kvB in little-endian (BIP 133 wire format).
let kvb = self.0.to_sat_per_kvb_ceil();
- FeeFilterEncoder(encoding::ArrayEncoder::without_length_prefix(kvb.to_le_bytes()))
+ FeeFilterEncoder::new(encoding::ArrayEncoder::without_length_prefix(kvb.to_le_bytes()))
}
}
@@ -776,7 +776,7 @@ impl encoding::Encoder for NetworkMessageEncoder {
encoding::encoder_newtype! {
/// Encoder for [`RawNetworkMessage`].
- pub struct RawNetworkMessageEncoder(
+ pub struct RawNetworkMessageEncoder<'e>(
encoding::Encoder2<
encoding::Encoder4<
encoding::ArrayEncoder<4>,
@@ -790,10 +790,10 @@ encoding::encoder_newtype! {
}
impl encoding::Encodable for RawNetworkMessage {
- type Encoder<'e> = RawNetworkMessageEncoder;
+ type Encoder<'e> = RawNetworkMessageEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- RawNetworkMessageEncoder(encoding::Encoder2::new(
+ RawNetworkMessageEncoder::new(encoding::Encoder2::new(
encoding::Encoder4::new(
encoding::ArrayEncoder::without_length_prefix(self.magic.to_bytes()),
self.command().encoder(),
diff --git a/p2p/src/message_blockdata.rs b/p2p/src/message_blockdata.rs
index bfe5e498..4c2b34a7 100644
--- a/p2p/src/message_blockdata.rs
+++ b/p2p/src/message_blockdata.rs
@@ -110,11 +110,11 @@ impl Decodable for Inventory {
encoding::encoder_newtype! {
/// The encoder for the [`Inventory`] type.
- pub struct InventoryEncoder(Encoder2<ArrayEncoder<4>, ArrayEncoder<32>>);
+ pub struct InventoryEncoder<'e>(Encoder2<ArrayEncoder<4>, ArrayEncoder<32>>);
}
impl encoding::Encodable for Inventory {
- type Encoder<'e> = InventoryEncoder;
+ type Encoder<'e> = InventoryEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
let (prefix, bytes) = match *self {
@@ -127,7 +127,7 @@ impl encoding::Encodable for Inventory {
Self::WitnessBlock(b) => (0x4000_0002, b.to_byte_array()),
Self::Unknown { inv_type: t, hash: d } => (t, d),
};
- InventoryEncoder(Encoder2::new(
+ InventoryEncoder::new(Encoder2::new(
ArrayEncoder::without_length_prefix(prefix.to_le_bytes()),
ArrayEncoder::without_length_prefix(bytes),
))
@@ -223,9 +223,9 @@ pub struct GetHeadersMessage {
}
type GetBlocksOrHeadersInnerEncoder<'e> = Encoder3<
- ProtocolVersionEncoder,
+ ProtocolVersionEncoder<'e>,
Encoder2<CompactSizeEncoder, SliceEncoder<'e, BlockHash>>,
- BlockHashEncoder,
+ BlockHashEncoder<'e>,
>;
encoding::encoder_newtype! {
@@ -245,7 +245,7 @@ impl encoding::Encodable for GetHeadersMessage {
Self: 'e;
fn encoder(&self) -> Self::Encoder<'_> {
- GetHeadersEncoder(Encoder3::new(
+ GetHeadersEncoder::new(Encoder3::new(
self.version.encoder(),
Encoder2::new(
CompactSizeEncoder::new(self.locator_hashes.len()),
@@ -263,7 +263,7 @@ impl encoding::Encodable for GetBlocksMessage {
Self: 'e;
fn encoder(&self) -> Self::Encoder<'_> {
- GetBlocksEncoder(Encoder3::new(
+ GetBlocksEncoder::new(Encoder3::new(
self.version.encoder(),
Encoder2::new(
CompactSizeEncoder::new(self.locator_hashes.len()),
diff --git a/p2p/src/message_bloom.rs b/p2p/src/message_bloom.rs
index 597212d9..fa6dea32 100644
--- a/p2p/src/message_bloom.rs
+++ b/p2p/src/message_bloom.rs
@@ -41,7 +41,7 @@ encoding::encoder_newtype! {
Encoder3<
ArrayEncoder<4>,
ArrayEncoder<4>,
- BloomFlagsEncoder
+ BloomFlagsEncoder<'e>
>
>
);
@@ -51,7 +51,7 @@ impl encoding::Encodable for FilterLoad {
type Encoder<'e> = FilterLoadEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- FilterLoadEncoder(Encoder2::new(
+ FilterLoadEncoder::new(Encoder2::new(
Encoder2::new(
CompactSizeEncoder::new(self.filter.len()),
BytesEncoder::without_length_prefix(&self.filter),
@@ -142,18 +142,20 @@ pub enum BloomFlags {
encoding::encoder_newtype! {
/// The encoder for [`BloomFlags`].
- pub struct BloomFlagsEncoder(ArrayEncoder<1>);
+ pub struct BloomFlagsEncoder<'e>(ArrayEncoder<1>);
}
impl encoding::Encodable for BloomFlags {
- type Encoder<'e> = BloomFlagsEncoder;
+ type Encoder<'e> = BloomFlagsEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- BloomFlagsEncoder(ArrayEncoder::without_length_prefix([match self {
- Self::None => 0,
- Self::All => 1,
- Self::PubkeyOnly => 2,
- }]))
+ BloomFlagsEncoder::new(ArrayEncoder::without_length_prefix(
+ [match self {
+ Self::None => 0,
+ Self::All => 1,
+ Self::PubkeyOnly => 2,
+ }]
+ ))
}
}
@@ -271,10 +273,12 @@ impl encoding::Encodable for FilterAdd {
type Encoder<'e> = FilterAddEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- FilterAddEncoder(Encoder2::new(
- CompactSizeEncoder::new(self.data.len()),
- BytesEncoder::without_length_prefix(&self.data),
- ))
+ FilterAddEncoder::new(
+ Encoder2::new(
+ CompactSizeEncoder::new(self.data.len()),
+ BytesEncoder::without_length_prefix(&self.data)
+ )
+ )
}
}
diff --git a/p2p/src/message_filter.rs b/p2p/src/message_filter.rs
index 4c9f8928..f7a464d4 100644
--- a/p2p/src/message_filter.rs
+++ b/p2p/src/message_filter.rs
@@ -64,27 +64,27 @@ impl_hashencode!(FilterHeader);
encoding::encoder_newtype! {
/// Encoder type for [`FilterHash`].
- pub struct FilterHashEncoder(ArrayEncoder<32>);
+ pub struct FilterHashEncoder<'e>(ArrayEncoder<32>);
}
impl encoding::Encodable for FilterHash {
- type Encoder<'e> = FilterHashEncoder;
+ type Encoder<'e> = FilterHashEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- FilterHashEncoder(ArrayEncoder::without_length_prefix(self.to_byte_array()))
+ FilterHashEncoder::new(ArrayEncoder::without_length_prefix(self.to_byte_array()))
}
}
encoding::encoder_newtype! {
/// Encoder type for [`FilterHeader`].
- pub struct FilterHeaderEncoder(ArrayEncoder<32>);
+ pub struct FilterHeaderEncoder<'e>(ArrayEncoder<32>);
}
impl encoding::Encodable for FilterHeader {
- type Encoder<'e> = FilterHeaderEncoder;
+ type Encoder<'e> = FilterHeaderEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- FilterHeaderEncoder(ArrayEncoder::without_length_prefix(self.to_byte_array()))
+ FilterHeaderEncoder::new(ArrayEncoder::without_length_prefix(self.to_byte_array()))
}
}
@@ -211,14 +211,14 @@ pub struct GetCFilters {
encoding::encoder_newtype! {
/// Encoder type for the [`GetCFilters`] message.
- pub struct GetCFiltersEncoder(Encoder3<ArrayEncoder<1>, BlockHeightEncoder, BlockHashEncoder>);
+ pub struct GetCFiltersEncoder<'e>(Encoder3<ArrayEncoder<1>, BlockHeightEncoder<'e>, BlockHashEncoder<'e>>);
}
impl encoding::Encodable for GetCFilters {
- type Encoder<'e> = GetCFiltersEncoder;
+ type Encoder<'e> = GetCFiltersEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- GetCFiltersEncoder(Encoder3::new(
+ GetCFiltersEncoder::new(Encoder3::new(
ArrayEncoder::without_length_prefix(self.filter_type.to_le_bytes()),
self.start_height.encoder(),
self.stop_hash.encoder(),
@@ -299,7 +299,7 @@ encoding::encoder_newtype! {
pub struct CFilterEncoder<'e>(
Encoder3<
ArrayEncoder<1>,
- BlockHashEncoder,
+ BlockHashEncoder<'e>,
Encoder2<CompactSizeEncoder, BytesEncoder<'e>>,
>
);
@@ -312,7 +312,7 @@ impl encoding::Encodable for CFilter {
Self: 'e;
fn encoder(&self) -> Self::Encoder<'_> {
- CFilterEncoder(Encoder3::new(
+ CFilterEncoder::new(Encoder3::new(
ArrayEncoder::without_length_prefix(self.filter_type.to_le_bytes()),
self.block_hash.encoder(),
Encoder2::new(
@@ -393,14 +393,14 @@ pub struct GetCFHeaders {
encoding::encoder_newtype! {
/// Encoder type for the [`GetCFHeaders`] message.
- pub struct GetCFHeadersEncoder(Encoder3<ArrayEncoder<1>, BlockHeightEncoder, BlockHashEncoder>);
+ pub struct GetCFHeadersEncoder<'e>(Encoder3<ArrayEncoder<1>, BlockHeightEncoder<'e>, BlockHashEncoder<'e>>);
}
impl encoding::Encodable for GetCFHeaders {
- type Encoder<'e> = GetCFHeadersEncoder;
+ type Encoder<'e> = GetCFHeadersEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- GetCFHeadersEncoder(Encoder3::new(
+ GetCFHeadersEncoder::new(Encoder3::new(
ArrayEncoder::without_length_prefix(self.filter_type.to_le_bytes()),
self.start_height.encoder(),
self.stop_hash.encoder(),
@@ -483,8 +483,8 @@ encoding::encoder_newtype! {
pub struct CFHeadersEncoder<'e>(
Encoder4<
ArrayEncoder<1>,
- BlockHashEncoder,
- FilterHeaderEncoder,
+ BlockHashEncoder<'e>,
+ FilterHeaderEncoder<'e>,
Encoder2<CompactSizeEncoder, SliceEncoder<'e, FilterHash>>
>
);
@@ -494,7 +494,7 @@ impl encoding::Encodable for CFHeaders {
type Encoder<'e> = CFHeadersEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- CFHeadersEncoder(Encoder4::new(
+ CFHeadersEncoder::new(Encoder4::new(
ArrayEncoder::without_length_prefix(self.filter_type.to_le_bytes()),
self.stop_hash.encoder(),
self.previous_filter_header.encoder(),
@@ -581,14 +581,14 @@ pub struct GetCFCheckpt {
encoding::encoder_newtype! {
/// Encoder type for the [`GetCFCheckpt`] message.
- pub struct GetCFCheckptEncoder(Encoder2<ArrayEncoder<1>, BlockHashEncoder>);
+ pub struct GetCFCheckptEncoder<'e>(Encoder2<ArrayEncoder<1>, BlockHashEncoder<'e>>);
}
impl encoding::Encodable for GetCFCheckpt {
- type Encoder<'e> = GetCFCheckptEncoder;
+ type Encoder<'e> = GetCFCheckptEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- GetCFCheckptEncoder(Encoder2::new(
+ GetCFCheckptEncoder::new(Encoder2::new(
ArrayEncoder::without_length_prefix(self.filter_type.to_le_bytes()),
self.stop_hash.encoder(),
))
@@ -664,7 +664,7 @@ encoding::encoder_newtype! {
pub struct CFCheckptEncoder<'e>(
Encoder3<
ArrayEncoder<1>,
- BlockHashEncoder,
+ BlockHashEncoder<'e>,
Encoder2<CompactSizeEncoder, SliceEncoder<'e, FilterHeader>>
>
);
@@ -677,7 +677,7 @@ impl encoding::Encodable for CFCheckpt {
Self: 'e;
fn encoder(&self) -> Self::Encoder<'_> {
- CFCheckptEncoder(Encoder3::new(
+ CFCheckptEncoder::new(Encoder3::new(
ArrayEncoder::without_length_prefix(self.filter_type.to_le_bytes()),
self.stop_hash.encoder(),
Encoder2::new(
diff --git a/p2p/src/message_network.rs b/p2p/src/message_network.rs
index b241b2db..6e913807 100644
--- a/p2p/src/message_network.rs
+++ b/p2p/src/message_network.rs
@@ -119,10 +119,12 @@ impl encoding::Encodable for UserAgent {
type Encoder<'e> = UserAgentEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- UserAgentEncoder(Encoder2::new(
- CompactSizeEncoder::new(self.user_agent.len()),
- BytesEncoder::without_length_prefix(self.user_agent.as_bytes()),
- ))
+ UserAgentEncoder::new(
+ Encoder2::new(
+ CompactSizeEncoder::new(self.user_agent.len()),
+ BytesEncoder::without_length_prefix(self.user_agent.as_bytes())
+ )
+ )
}
}
@@ -358,14 +360,14 @@ pub enum RejectReason {
encoding::encoder_newtype! {
/// The encoder type for a [`RejectReason`].
- pub struct RejectReasonEncoder(ArrayEncoder<1>);
+ pub struct RejectReasonEncoder<'e>(ArrayEncoder<1>);
}
impl encoding::Encodable for RejectReason {
- type Encoder<'e> = RejectReasonEncoder;
+ type Encoder<'e> = RejectReasonEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- RejectReasonEncoder(ArrayEncoder::without_length_prefix([*self as u8]))
+ RejectReasonEncoder::new(ArrayEncoder::without_length_prefix([*self as u8]))
}
}
@@ -481,7 +483,7 @@ encoding::encoder_newtype! {
pub struct RejectEncoder<'e>(
Encoder4<
Encoder2<CompactSizeEncoder, BytesEncoder<'e>>,
- RejectReasonEncoder,
+ RejectReasonEncoder<'e>,
Encoder2<CompactSizeEncoder, BytesEncoder<'e>>,
ArrayEncoder<32>,
>
@@ -492,18 +494,20 @@ impl encoding::Encodable for Reject {
type Encoder<'e> = RejectEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- RejectEncoder(Encoder4::new(
- Encoder2::new(
- CompactSizeEncoder::new(self.message.len()),
- BytesEncoder::without_length_prefix(self.message.as_bytes()),
- ),
- self.ccode.encoder(),
- Encoder2::new(
- CompactSizeEncoder::new(self.reason.len()),
- BytesEncoder::without_length_prefix(self.reason.as_bytes()),
- ),
- ArrayEncoder::without_length_prefix(self.hash.to_byte_array()),
- ))
+ RejectEncoder::new(
+ Encoder4::new(
+ Encoder2::new(
+ CompactSizeEncoder::new(self.message.len()),
+ BytesEncoder::without_length_prefix(self.message.as_bytes())
+ ),
+ self.ccode.encoder(),
+ Encoder2::new(
+ CompactSizeEncoder::new(self.reason.len()),
+ BytesEncoder::without_length_prefix(self.reason.as_bytes())
+ ),
+ ArrayEncoder::without_length_prefix(self.hash.to_byte_array()),
+ )
+ )
}
}
@@ -618,7 +622,7 @@ impl encoding::Encodable for Alert {
type Encoder<'e> = AlertEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- AlertEncoder(Encoder2::new(
+ AlertEncoder::new(Encoder2::new(
CompactSizeEncoder::new(self.0.len()),
BytesEncoder::without_length_prefix(&self.0),
))
diff --git a/primitives/src/block.rs b/primitives/src/block.rs
index 052ac10b..8e13836b 100644
--- a/primitives/src/block.rs
+++ b/primitives/src/block.rs
@@ -281,14 +281,14 @@ mod sealed {
encoding::encoder_newtype! {
/// The encoder for the [`Block`] type.
pub struct BlockEncoder<'e>(
- Encoder2<HeaderEncoder, Encoder2<CompactSizeEncoder, SliceEncoder<'e, Transaction>>>
+ Encoder2<HeaderEncoder<'e>, Encoder2<CompactSizeEncoder, SliceEncoder<'e, Transaction>>>
);
}
#[cfg(feature = "alloc")]
impl Encodable for Block {
type Encoder<'e>
- = Encoder2<HeaderEncoder, Encoder2<CompactSizeEncoder, SliceEncoder<'e, Transaction>>>
+ = Encoder2<HeaderEncoder<'e>, Encoder2<CompactSizeEncoder, SliceEncoder<'e, Transaction>>>
where
Self: 'e;
@@ -578,23 +578,23 @@ impl std::error::Error for ParseHeaderError {
encoding::encoder_newtype_exact! {
/// The encoder for the [`Header`] type.
- pub struct HeaderEncoder(
+ pub struct HeaderEncoder<'e>(
encoding::Encoder6<
- VersionEncoder,
- BlockHashEncoder,
- crate::merkle_tree::TxMerkleNodeEncoder,
- crate::time::BlockTimeEncoder,
- crate::pow::CompactTargetEncoder,
+ VersionEncoder<'e>,
+ BlockHashEncoder<'e>,
+ crate::merkle_tree::TxMerkleNodeEncoder<'e>,
+ crate::time::BlockTimeEncoder<'e>,
+ crate::pow::CompactTargetEncoder<'e>,
encoding::ArrayEncoder<4>,
>
);
}
impl Encodable for Header {
- type Encoder<'e> = HeaderEncoder;
+ type Encoder<'e> = HeaderEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- HeaderEncoder(encoding::Encoder6::new(
+ HeaderEncoder::new(encoding::Encoder6::new(
self.version.encoder(),
self.prev_blockhash.encoder(),
self.merkle_root.encoder(),
@@ -807,13 +807,13 @@ impl Default for Version {
encoding::encoder_newtype_exact! {
/// The encoder for the [`Version`] type.
- pub struct VersionEncoder(encoding::ArrayEncoder<4>);
+ pub struct VersionEncoder<'e>(encoding::ArrayEncoder<4>);
}
impl Encodable for Version {
- type Encoder<'e> = VersionEncoder;
+ type Encoder<'e> = VersionEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- VersionEncoder(encoding::ArrayEncoder::without_length_prefix(
+ VersionEncoder::new(encoding::ArrayEncoder::without_length_prefix(
self.to_consensus().to_le_bytes(),
))
}
diff --git a/primitives/src/hash_types/block_hash.rs b/primitives/src/hash_types/block_hash.rs
index f92ffa9b..99c666d8 100644
--- a/primitives/src/hash_types/block_hash.rs
+++ b/primitives/src/hash_types/block_hash.rs
@@ -31,13 +31,13 @@ include!("./generic.rs");
encoding::encoder_newtype_exact! {
/// The encoder for the [`BlockHash`] type.
- pub struct BlockHashEncoder(encoding::ArrayEncoder<32>);
+ pub struct BlockHashEncoder<'e>(encoding::ArrayEncoder<32>);
}
impl Encodable for BlockHash {
- type Encoder<'e> = BlockHashEncoder;
+ type Encoder<'e> = BlockHashEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- BlockHashEncoder(encoding::ArrayEncoder::without_length_prefix(self.to_byte_array()))
+ BlockHashEncoder::new(encoding::ArrayEncoder::without_length_prefix(self.to_byte_array()))
}
}
diff --git a/primitives/src/hash_types/transaction_merkle_node.rs b/primitives/src/hash_types/transaction_merkle_node.rs
index 42e8c485..ce115fd9 100644
--- a/primitives/src/hash_types/transaction_merkle_node.rs
+++ b/primitives/src/hash_types/transaction_merkle_node.rs
@@ -50,13 +50,13 @@ impl TxMerkleNode {
encoding::encoder_newtype_exact! {
/// The encoder for the [`TxMerkleNode`] type.
- pub struct TxMerkleNodeEncoder(encoding::ArrayEncoder<32>);
+ pub struct TxMerkleNodeEncoder<'e>(encoding::ArrayEncoder<32>);
}
impl encoding::Encodable for TxMerkleNode {
- type Encoder<'e> = TxMerkleNodeEncoder;
+ type Encoder<'e> = TxMerkleNodeEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- TxMerkleNodeEncoder(encoding::ArrayEncoder::without_length_prefix(self.to_byte_array()))
+ TxMerkleNodeEncoder::new(encoding::ArrayEncoder::without_length_prefix(self.to_byte_array()))
}
}
diff --git a/primitives/src/hash_types/witness_merkle_node.rs b/primitives/src/hash_types/witness_merkle_node.rs
index 7cc59e5b..111ff525 100644
--- a/primitives/src/hash_types/witness_merkle_node.rs
+++ b/primitives/src/hash_types/witness_merkle_node.rs
@@ -50,13 +50,13 @@ impl WitnessMerkleNode {
encoding::encoder_newtype_exact! {
/// The encoder for the [`WitnessMerkleNode`] type.
- pub struct WitnessMerkleNodeEncoder(encoding::ArrayEncoder<32>);
+ pub struct WitnessMerkleNodeEncoder<'e>(encoding::ArrayEncoder<32>);
}
impl encoding::Encodable for WitnessMerkleNode {
- type Encoder<'e> = WitnessMerkleNodeEncoder;
+ type Encoder<'e> = WitnessMerkleNodeEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- WitnessMerkleNodeEncoder(encoding::ArrayEncoder::without_length_prefix(
+ WitnessMerkleNodeEncoder::new(encoding::ArrayEncoder::without_length_prefix(
self.to_byte_array(),
))
}
diff --git a/primitives/src/pow.rs b/primitives/src/pow.rs
index a7f1c813..02dd7d94 100644
--- a/primitives/src/pow.rs
+++ b/primitives/src/pow.rs
@@ -53,13 +53,13 @@ impl fmt::UpperHex for CompactTarget {
encoding::encoder_newtype_exact! {
/// The encoder for the [`CompactTarget`] type.
- pub struct CompactTargetEncoder(encoding::ArrayEncoder<4>);
+ pub struct CompactTargetEncoder<'e>(encoding::ArrayEncoder<4>);
}
impl encoding::Encodable for CompactTarget {
- type Encoder<'e> = CompactTargetEncoder;
+ type Encoder<'e> = CompactTargetEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- CompactTargetEncoder(encoding::ArrayEncoder::without_length_prefix(
+ CompactTargetEncoder::new(encoding::ArrayEncoder::without_length_prefix(
self.to_consensus().to_le_bytes(),
))
}
diff --git a/primitives/src/script/borrowed.rs b/primitives/src/script/borrowed.rs
index 01e59d67..ce092a14 100644
--- a/primitives/src/script/borrowed.rs
+++ b/primitives/src/script/borrowed.rs
@@ -165,7 +165,7 @@ impl<T> Encodable for Script<T> {
Self: 'a;
fn encoder(&self) -> Self::Encoder<'_> {
- ScriptEncoder(Encoder2::new(
+ ScriptEncoder::new(Encoder2::new(
CompactSizeEncoder::new(self.as_bytes().len()),
BytesEncoder::without_length_prefix(self.as_bytes()),
))
diff --git a/primitives/src/transaction.rs b/primitives/src/transaction.rs
index 7abeb739..00aa9a2d 100644
--- a/primitives/src/transaction.rs
+++ b/primitives/src/transaction.rs
@@ -324,12 +324,12 @@ fn hash_transaction(tx: &Transaction, uses_segwit_serialization: bool) -> sha256
#[cfg(feature = "alloc")]
type TransactionEncoderInner<'e> = Encoder6<
- VersionEncoder,
+ VersionEncoder<'e>,
Option<ArrayEncoder<2>>,
Encoder2<CompactSizeEncoder, SliceEncoder<'e, TxIn>>,
Encoder2<CompactSizeEncoder, SliceEncoder<'e, TxOut>>,
Option<WitnessesEncoder<'e>>,
- LockTimeEncoder,
+ LockTimeEncoder<'e>,
>;
#[cfg(feature = "alloc")]
@@ -360,7 +360,7 @@ impl Encodable for Transaction {
if self.uses_segwit_serialization() {
let segwit = ArrayEncoder::without_length_prefix([0x00, 0x01]);
let witnesses = WitnessesEncoder::new(self.inputs.as_slice());
- TransactionEncoder(Encoder6::new(
+ TransactionEncoder::new(Encoder6::new(
version,
Some(segwit),
inputs,
@@ -369,7 +369,7 @@ impl Encodable for Transaction {
lock_time,
))
} else {
- TransactionEncoder(Encoder6::new(version, None, inputs, outputs, None, lock_time))
+ TransactionEncoder::new(Encoder6::new(version, None, inputs, outputs, None, lock_time))
}
}
}
@@ -887,14 +887,14 @@ impl TxIn {
encoding::encoder_newtype! {
/// The encoder for the [`TxIn`] type.
pub struct TxInEncoder<'e>(
- Encoder3<OutPointEncoder<'e>, ScriptEncoder<'e>, SequenceEncoder>
+ Encoder3<OutPointEncoder<'e>, ScriptEncoder<'e>, SequenceEncoder<'e>>
);
}
#[cfg(feature = "alloc")]
impl Encodable for TxIn {
type Encoder<'e>
- = Encoder3<OutPointEncoder<'e>, ScriptEncoder<'e>, SequenceEncoder>
+ = Encoder3<OutPointEncoder<'e>, ScriptEncoder<'e>, SequenceEncoder<'e>>
where
Self: 'e;
@@ -1054,13 +1054,13 @@ pub struct TxOut {
#[cfg(feature = "alloc")]
encoding::encoder_newtype! {
/// The encoder for the [`TxOut`] type.
- pub struct TxOutEncoder<'e>(Encoder2<AmountEncoder, ScriptEncoder<'e>>);
+ pub struct TxOutEncoder<'e>(Encoder2<AmountEncoder<'e>, ScriptEncoder<'e>>);
}
#[cfg(feature = "alloc")]
impl Encodable for TxOut {
type Encoder<'e>
- = Encoder2<AmountEncoder, ScriptEncoder<'e>>
+ = Encoder2<AmountEncoder<'e>, ScriptEncoder<'e>>
where
Self: 'e;
@@ -1170,7 +1170,7 @@ impl Encodable for OutPoint {
Self: 'e;
fn encoder(&self) -> Self::Encoder<'_> {
- OutPointEncoder(Encoder2::new(
+ OutPointEncoder::new(Encoder2::new(
BytesEncoder::without_length_prefix(self.txid.as_byte_array()),
ArrayEncoder::without_length_prefix(self.vout.to_le_bytes()),
))
@@ -1505,13 +1505,13 @@ impl From<Version> for u32 {
encoding::encoder_newtype_exact! {
/// The encoder for the [`Version`] type.
- pub struct VersionEncoder(encoding::ArrayEncoder<4>);
+ pub struct VersionEncoder<'e>(encoding::ArrayEncoder<4>);
}
impl encoding::Encodable for Version {
- type Encoder<'e> = VersionEncoder;
+ type Encoder<'e> = VersionEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- VersionEncoder(encoding::ArrayEncoder::without_length_prefix(self.to_u32().to_le_bytes()))
+ VersionEncoder::new(encoding::ArrayEncoder::without_length_prefix(self.to_u32().to_le_bytes()))
}
}
diff --git a/units/src/amount/unsigned.rs b/units/src/amount/unsigned.rs
index 88e5d843..3443fce5 100644
--- a/units/src/amount/unsigned.rs
+++ b/units/src/amount/unsigned.rs
@@ -559,14 +559,14 @@ impl TryFrom<SignedAmount> for Amount {
#[cfg(feature = "encoding")]
encoding::encoder_newtype_exact! {
/// The encoder for the [`Amount`] type.
- pub struct AmountEncoder(encoding::ArrayEncoder<8>);
+ pub struct AmountEncoder<'e>(encoding::ArrayEncoder<8>);
}
#[cfg(feature = "encoding")]
impl encoding::Encodable for Amount {
- type Encoder<'e> = AmountEncoder;
+ type Encoder<'e> = AmountEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- AmountEncoder(encoding::ArrayEncoder::without_length_prefix(self.to_sat().to_le_bytes()))
+ AmountEncoder::new(encoding::ArrayEncoder::without_length_prefix(self.to_sat().to_le_bytes()))
}
}
diff --git a/units/src/block.rs b/units/src/block.rs
index 77e9fec8..a5f45ee5 100644
--- a/units/src/block.rs
+++ b/units/src/block.rs
@@ -146,14 +146,14 @@ impl TryFrom<BlockHeight> for absolute::Height {
#[cfg(feature = "encoding")]
encoding::encoder_newtype_exact! {
/// The encoder for the [`BlockHeight`] type.
- pub struct BlockHeightEncoder(encoding::ArrayEncoder<4>);
+ pub struct BlockHeightEncoder<'e>(encoding::ArrayEncoder<4>);
}
#[cfg(feature = "encoding")]
impl encoding::Encodable for BlockHeight {
- type Encoder<'e> = BlockHeightEncoder;
+ type Encoder<'e> = BlockHeightEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- BlockHeightEncoder(encoding::ArrayEncoder::without_length_prefix(
+ BlockHeightEncoder::new(encoding::ArrayEncoder::without_length_prefix(
self.to_u32().to_le_bytes(),
))
}
diff --git a/units/src/locktime/absolute/mod.rs b/units/src/locktime/absolute/mod.rs
index 93c6e8c1..360ccdf9 100644
--- a/units/src/locktime/absolute/mod.rs
+++ b/units/src/locktime/absolute/mod.rs
@@ -400,14 +400,14 @@ parse_int::impl_parse_str_from_int_infallible!(LockTime, u32, from_consensus);
#[cfg(feature = "encoding")]
encoding::encoder_newtype_exact! {
/// The encoder for the [`LockTime`] type.
- pub struct LockTimeEncoder(encoding::ArrayEncoder<4>);
+ pub struct LockTimeEncoder<'e>(encoding::ArrayEncoder<4>);
}
#[cfg(feature = "encoding")]
impl encoding::Encodable for LockTime {
- type Encoder<'e> = LockTimeEncoder;
+ type Encoder<'e> = LockTimeEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- LockTimeEncoder(encoding::ArrayEncoder::without_length_prefix(
+ LockTimeEncoder::new(encoding::ArrayEncoder::without_length_prefix(
self.to_consensus_u32().to_le_bytes(),
))
}
diff --git a/units/src/sequence.rs b/units/src/sequence.rs
index 2cd29415..b7271e5d 100644
--- a/units/src/sequence.rs
+++ b/units/src/sequence.rs
@@ -269,14 +269,14 @@ parse_int::impl_parse_str_from_int_infallible!(Sequence, u32, from_consensus);
#[cfg(feature = "encoding")]
encoding::encoder_newtype_exact! {
/// The encoder for the [`Sequence`] type.
- pub struct SequenceEncoder(encoding::ArrayEncoder<4>);
+ pub struct SequenceEncoder<'e>(encoding::ArrayEncoder<4>);
}
#[cfg(feature = "encoding")]
impl encoding::Encodable for Sequence {
- type Encoder<'e> = SequenceEncoder;
+ type Encoder<'e> = SequenceEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- SequenceEncoder(encoding::ArrayEncoder::without_length_prefix(
+ SequenceEncoder::new(encoding::ArrayEncoder::without_length_prefix(
self.to_consensus_u32().to_le_bytes(),
))
}
diff --git a/units/src/time.rs b/units/src/time.rs
index b2f9e976..9a2a3d60 100644
--- a/units/src/time.rs
+++ b/units/src/time.rs
@@ -83,14 +83,14 @@ impl<'de> Deserialize<'de> for BlockTime {
#[cfg(feature = "encoding")]
encoding::encoder_newtype_exact! {
/// The encoder for the [`BlockTime`] type.
- pub struct BlockTimeEncoder(encoding::ArrayEncoder<4>);
+ pub struct BlockTimeEncoder<'e>(encoding::ArrayEncoder<4>);
}
#[cfg(feature = "encoding")]
impl encoding::Encodable for BlockTime {
- type Encoder<'e> = BlockTimeEncoder;
+ type Encoder<'e> = BlockTimeEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
- BlockTimeEncoder(encoding::ArrayEncoder::without_length_prefix(self.to_u32().to_le_bytes()))
+ BlockTimeEncoder::new(encoding::ArrayEncoder::without_length_prefix(self.to_u32().to_le_bytes()))
}
}
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.