Merge rust-bitcoin/rust-bitcoin#6668: Scrub the transaction encoding logic
What changed, and why it matters
This commit is a pure code reorganization (refactor) in the rust-bitcoin library. It moves transaction encoding and decoding definitions around within a single file so the code follows the project's preferred layout. No logic, behavior, or security properties were changed.
No action required. This is a non-security code-movement refactor.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit reorders items in primitives/src/transaction.rs: Encode/Decode trait implementations and encoder/decoder struct definitions for TxIn, TxOut, OutPoint, and Version are moved to a consistent order. The diff shows only additions and removals of the same lines in different positions; there are no functional changes, no new code, and no changes to encoding semantics.
Changed components
primitives/src/transaction.rsInspect captured patch +57 / −57
### primitives/src/transaction.rs
@@ -746,12 +746,8 @@ impl TxIn {
}
#[cfg(feature = "alloc")]
-encoding::encoder_newtype_exact! {
- /// The encoder for the [`TxIn`] type.
- #[derive(Debug, Clone)]
- pub struct TxInEncoder<'e>(
- Encoder3<OutPointEncoder<'e>, ScriptEncoder<'e>, SequenceEncoder<'e>>
- );
+impl encoding::Decode for TxIn {
+ type Decoder = TxInDecoder;
}
#[cfg(feature = "alloc")]
@@ -823,6 +819,15 @@ impl encoding::Encoder for WitnessesEncoder<'_> {
}
}
+#[cfg(feature = "alloc")]
+encoding::encoder_newtype_exact! {
+ /// The encoder for the [`TxIn`] type.
+ #[derive(Debug, Clone)]
+ pub struct TxInEncoder<'e>(
+ Encoder3<OutPointEncoder<'e>, ScriptEncoder<'e>, SequenceEncoder<'e>>
+ );
+}
+
#[cfg(feature = "alloc")]
type TxInInnerDecoder = Decoder3<OutPointDecoder, ScriptSigBufDecoder, SequenceDecoder>;
@@ -849,11 +854,6 @@ crate::decoder_newtype! {
}
}
-#[cfg(feature = "alloc")]
-impl encoding::Decode for TxIn {
- type Decoder = TxInDecoder;
-}
-
/// Bitcoin transaction output.
///
/// Defines new coins to be created as a result of the transaction,
@@ -874,13 +874,6 @@ pub struct TxOut {
pub script_pubkey: ScriptPubKeyBuf,
}
-#[cfg(feature = "alloc")]
-encoding::encoder_newtype_exact! {
- /// The encoder for the [`TxOut`] type.
- #[derive(Debug, Clone)]
- pub struct TxOutEncoder<'e>(Encoder2<AmountEncoder<'e>, ScriptEncoder<'e>>);
-}
-
#[cfg(feature = "alloc")]
impl encoding::Encode for TxOut {
type Encoder<'e>
@@ -893,6 +886,18 @@ impl encoding::Encode for TxOut {
}
}
+#[cfg(feature = "alloc")]
+impl encoding::Decode for TxOut {
+ type Decoder = TxOutDecoder;
+}
+
+#[cfg(feature = "alloc")]
+encoding::encoder_newtype_exact! {
+ /// The encoder for the [`TxOut`] type.
+ #[derive(Debug, Clone)]
+ pub struct TxOutEncoder<'e>(Encoder2<AmountEncoder<'e>, ScriptEncoder<'e>>);
+}
+
#[cfg(feature = "alloc")]
type TxOutInnerDecoder = Decoder2<AmountDecoder, ScriptPubKeyBufDecoder>;
@@ -915,11 +920,6 @@ crate::decoder_newtype! {
}
}
-#[cfg(feature = "alloc")]
-impl encoding::Decode for TxOut {
- type Decoder = TxOutDecoder;
-}
-
/// A reference to a transaction output.
///
/// # Bitcoin Core References
@@ -944,26 +944,6 @@ impl OutPoint {
pub const COINBASE_PREVOUT: Self = Self { txid: Txid::COINBASE_PREVOUT, vout: u32::MAX };
}
-encoding::encoder_newtype_exact! {
- /// The encoder for the [`OutPoint`] type.
- #[derive(Debug, Clone)]
- pub struct OutPointEncoder<'e>(Encoder2<BytesEncoder<'e>, ArrayEncoder<4>>);
-}
-
-impl encoding::Encode for OutPoint {
- type Encoder<'e>
- = OutPointEncoder<'e>
- where
- Self: 'e;
-
- fn encoder(&self) -> Self::Encoder<'_> {
- OutPointEncoder::new(Encoder2::new(
- BytesEncoder::without_length_prefix(self.txid.as_byte_array()),
- ArrayEncoder::without_length_prefix(self.vout.to_le_bytes()),
- ))
- }
-}
-
#[cfg(feature = "hex")]
impl fmt::Display for OutPoint {
#[inline]
@@ -1012,6 +992,30 @@ fn parse_vout(s: &str) -> Result<u32, ParseOutPointError> {
parse_int::int_from_str(s).map_err(ParseOutPointError::Vout)
}
+impl encoding::Encode for OutPoint {
+ type Encoder<'e>
+ = OutPointEncoder<'e>
+ where
+ Self: 'e;
+
+ fn encoder(&self) -> Self::Encoder<'_> {
+ OutPointEncoder::new(Encoder2::new(
+ BytesEncoder::without_length_prefix(self.txid.as_byte_array()),
+ ArrayEncoder::without_length_prefix(self.vout.to_le_bytes()),
+ ))
+ }
+}
+
+impl encoding::Decode for OutPoint {
+ type Decoder = OutPointDecoder;
+}
+
+encoding::encoder_newtype_exact! {
+ /// The encoder for the [`OutPoint`] type.
+ #[derive(Debug, Clone)]
+ pub struct OutPointEncoder<'e>(Encoder2<BytesEncoder<'e>, ArrayEncoder<4>>);
+}
+
crate::decoder_newtype! {
/// The decoder for the [`OutPoint`] type.
// 32 for the txid + 4 for the vout
@@ -1032,10 +1036,6 @@ crate::decoder_newtype! {
}
}
-impl encoding::Decode for OutPoint {
- type Decoder = OutPointDecoder;
-}
-
#[cfg(feature = "serde")]
impl Serialize for OutPoint {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -1226,12 +1226,6 @@ impl From<Version> for u32 {
fn from(version: Version) -> Self { version.0 }
}
-encoding::encoder_newtype_exact! {
- /// The encoder for the [`Version`] type.
- #[derive(Debug, Clone)]
- pub struct VersionEncoder<'e>(encoding::ArrayEncoder<4>);
-}
-
impl encoding::Encode for Version {
type Encoder<'e> = VersionEncoder<'e>;
fn encoder(&self) -> Self::Encoder<'_> {
@@ -1241,6 +1235,16 @@ impl encoding::Encode for Version {
}
}
+impl encoding::Decode for Version {
+ type Decoder = VersionDecoder;
+}
+
+encoding::encoder_newtype_exact! {
+ /// The encoder for the [`Version`] type.
+ #[derive(Debug, Clone)]
+ pub struct VersionEncoder<'e>(encoding::ArrayEncoder<4>);
+}
+
crate::decoder_newtype! {
/// The decoder for the [`Version`] type.
#[derive(Debug, Clone)]
@@ -1256,10 +1260,6 @@ crate::decoder_newtype! {
}
}
-impl encoding::Decode for Version {
- type Decoder = VersionDecoder;
-}
-
/// Error types for Bitcoin transactions.
pub mod error {
use core::convert::Infallible;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.