primitives: Convert encoders to ExactSizeEncoder
What changed, and why it matters
This is a routine library improvement that lets users ask 'how many bytes will this transaction input/output take up when encoded?' without actually encoding it. It adds a length method to two encoder types by switching to a macro that supports exact-size encoders. There is no security bug being fixed and no indication this change addresses any vulnerability.
No security action required. Treat as a normal API enhancement. If reviewing downstream impact, verify that any code depending on encoder behavior is not affected by the new ExactSizeEncoder implementation contract.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit changes TxInEncoder and TxOutEncoder in rust-bitcoin primitives from the encoder_newtype! macro to encoder_newtype_exact!. The new macro implements the ExactSizeEncoder trait, exposing a len() method that returns the encoded byte length. The diff only touches macro invocations and the generated public API surface (all-features.txt and alloc-only.txt). No logic changes, bounds checks, or memory-safety fixes are present.
Changed components
primitives/src/transaction.rsTxInEncoderTxOutEncoderbitcoin_consensus_encoding::encode::ExactSizeEncoder trait implementationInspect captured patch +10 / −2
diff --git a/api/primitives/all-features.txt b/api/primitives/all-features.txt
index 558784c7..a8d4929b 100644
--- a/api/primitives/all-features.txt
+++ b/api/primitives/all-features.txt
@@ -1013,6 +1013,8 @@ impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primit
impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primitives::merkle_tree::TxMerkleNodeEncoder<'e>
impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primitives::script::ScriptEncoder<'e>
impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primitives::transaction::OutPointEncoder<'e>
+impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primitives::transaction::TxInEncoder<'e>
+impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primitives::transaction::TxOutEncoder<'e>
impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primitives::transaction::VersionEncoder<'e>
impl<'e> bitcoin_primitives::transaction::WitnessesEncoder<'e>
impl<'e> core::marker::Freeze for bitcoin_primitives::block::BlockEncoder<'e>
@@ -1857,6 +1859,7 @@ pub fn bitcoin_primitives::transaction::TxInDecoderError::from(never: core::conv
pub fn bitcoin_primitives::transaction::TxInDecoderError::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)>
pub fn bitcoin_primitives::transaction::TxInEncoder<'e>::advance(&mut self) -> bool
pub fn bitcoin_primitives::transaction::TxInEncoder<'e>::current_chunk(&self) -> &[u8]
+pub fn bitcoin_primitives::transaction::TxInEncoder<'e>::len(&self) -> usize
pub fn bitcoin_primitives::transaction::TxOut::arbitrary(u: &mut arbitrary::unstructured::Unstructured<'a>) -> arbitrary::error::Result<Self>
pub fn bitcoin_primitives::transaction::TxOut::clone(&self) -> bitcoin_primitives::transaction::TxOut
pub fn bitcoin_primitives::transaction::TxOut::cmp(&self, other: &bitcoin_primitives::transaction::TxOut) -> core::cmp::Ordering
@@ -1876,6 +1879,7 @@ pub fn bitcoin_primitives::transaction::TxOutDecoderError::from(never: core::con
pub fn bitcoin_primitives::transaction::TxOutDecoderError::source(&self) -> core::option::Option<&(dyn core::error::Error + 'static)>
pub fn bitcoin_primitives::transaction::TxOutEncoder<'e>::advance(&mut self) -> bool
pub fn bitcoin_primitives::transaction::TxOutEncoder<'e>::current_chunk(&self) -> &[u8]
+pub fn bitcoin_primitives::transaction::TxOutEncoder<'e>::len(&self) -> usize
pub fn bitcoin_primitives::transaction::Version::arbitrary(u: &mut arbitrary::unstructured::Unstructured<'a>) -> arbitrary::error::Result<Self>
pub fn bitcoin_primitives::transaction::Version::clone(&self) -> bitcoin_primitives::transaction::Version
pub fn bitcoin_primitives::transaction::Version::cmp(&self, other: &bitcoin_primitives::transaction::Version) -> core::cmp::Ordering
diff --git a/api/primitives/alloc-only.txt b/api/primitives/alloc-only.txt
index 23a790e3..66124885 100644
--- a/api/primitives/alloc-only.txt
+++ b/api/primitives/alloc-only.txt
@@ -853,6 +853,8 @@ impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primit
impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primitives::merkle_tree::TxMerkleNodeEncoder<'e>
impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primitives::script::ScriptEncoder<'e>
impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primitives::transaction::OutPointEncoder<'e>
+impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primitives::transaction::TxInEncoder<'e>
+impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primitives::transaction::TxOutEncoder<'e>
impl<'e> bitcoin_consensus_encoding::encode::ExactSizeEncoder for bitcoin_primitives::transaction::VersionEncoder<'e>
impl<'e> bitcoin_primitives::transaction::WitnessesEncoder<'e>
impl<'e> core::marker::Freeze for bitcoin_primitives::block::BlockEncoder<'e>
@@ -1597,6 +1599,7 @@ pub fn bitcoin_primitives::transaction::TxInDecoderError::fmt(&self, f: &mut cor
pub fn bitcoin_primitives::transaction::TxInDecoderError::from(never: core::convert::Infallible) -> Self
pub fn bitcoin_primitives::transaction::TxInEncoder<'e>::advance(&mut self) -> bool
pub fn bitcoin_primitives::transaction::TxInEncoder<'e>::current_chunk(&self) -> &[u8]
+pub fn bitcoin_primitives::transaction::TxInEncoder<'e>::len(&self) -> usize
pub fn bitcoin_primitives::transaction::TxOut::clone(&self) -> bitcoin_primitives::transaction::TxOut
pub fn bitcoin_primitives::transaction::TxOut::cmp(&self, other: &bitcoin_primitives::transaction::TxOut) -> core::cmp::Ordering
pub fn bitcoin_primitives::transaction::TxOut::decoder() -> Self::Decoder
@@ -1614,6 +1617,7 @@ pub fn bitcoin_primitives::transaction::TxOutDecoderError::fmt(&self, f: &mut co
pub fn bitcoin_primitives::transaction::TxOutDecoderError::from(never: core::convert::Infallible) -> Self
pub fn bitcoin_primitives::transaction::TxOutEncoder<'e>::advance(&mut self) -> bool
pub fn bitcoin_primitives::transaction::TxOutEncoder<'e>::current_chunk(&self) -> &[u8]
+pub fn bitcoin_primitives::transaction::TxOutEncoder<'e>::len(&self) -> usize
pub fn bitcoin_primitives::transaction::Version::clone(&self) -> bitcoin_primitives::transaction::Version
pub fn bitcoin_primitives::transaction::Version::cmp(&self, other: &bitcoin_primitives::transaction::Version) -> core::cmp::Ordering
pub fn bitcoin_primitives::transaction::Version::decoder() -> Self::Decoder
diff --git a/primitives/src/transaction.rs b/primitives/src/transaction.rs
index a4284e65..ed8073c6 100644
--- a/primitives/src/transaction.rs
+++ b/primitives/src/transaction.rs
@@ -887,7 +887,7 @@ impl TxIn {
}
#[cfg(feature = "alloc")]
-encoding::encoder_newtype! {
+encoding::encoder_newtype_exact! {
/// The encoder for the [`TxIn`] type.
pub struct TxInEncoder<'e>(
Encoder3<OutPointEncoder<'e>, ScriptEncoder<'e>, SequenceEncoder<'e>>
@@ -1045,7 +1045,7 @@ pub struct TxOut {
}
#[cfg(feature = "alloc")]
-encoding::encoder_newtype! {
+encoding::encoder_newtype_exact! {
/// The encoder for the [`TxOut`] type.
pub struct TxOutEncoder<'e>(Encoder2<AmountEncoder<'e>, ScriptEncoder<'e>>);
}
Why this scored 19/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.