What changed, and why it matters
This commit simply hides an internal helper type called WitnessesEncoder from public view. It is a routine API-cleanup change with no security relevance visible in the code or commit message.
No security action needed; treat as normal API visibility cleanup.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch removes WitnessesEncoder from the public re-export list in bitcoin/src/blockdata/transaction.rs and changes its visibility from pub struct to struct in primitives/src/transaction.rs, moving the code closer to where it is used. No logic changes, no bug fixes, and no security claims are present.
Changed components
bitcoin/src/blockdata/transaction.rsprimitives/src/transaction.rsInspect captured patch +54 / −54
diff --git a/bitcoin/src/blockdata/transaction.rs b/bitcoin/src/blockdata/transaction.rs
index 7d791b26..1b73014f 100644
--- a/bitcoin/src/blockdata/transaction.rs
+++ b/bitcoin/src/blockdata/transaction.rs
@@ -36,7 +36,7 @@ pub use primitives::transaction::BlockHashDecoderError;
pub use primitives::transaction::{
BlockHashDecoder, Ntxid, OutPoint, OutPointDecoder, OutPointEncoder, Transaction,
TransactionDecoder, TransactionEncoder, TxIn, TxInDecoder, TxInEncoder, TxOut, TxOutDecoder,
- TxOutEncoder, Txid, Version, VersionDecoder, VersionEncoder, WitnessesEncoder, Wtxid,
+ TxOutEncoder, Txid, Version, VersionDecoder, VersionEncoder, Wtxid,
};
#[doc(no_inline)]
diff --git a/primitives/src/transaction.rs b/primitives/src/transaction.rs
index 0b9ad119..c530f5ca 100644
--- a/primitives/src/transaction.rs
+++ b/primitives/src/transaction.rs
@@ -695,6 +695,59 @@ enum IsSegwit {
No,
}
+/// Encodes the witnesses from a list of inputs.
+#[cfg(feature = "alloc")]
+#[derive(Debug, Clone)]
+struct WitnessesEncoder<'e> {
+ inputs: &'e [TxIn],
+ /// Encoder for the current witness being encoded.
+ cur_enc: Option<WitnessEncoder<'e>>,
+}
+
+#[cfg(feature = "alloc")]
+impl<'e> WitnessesEncoder<'e> {
+ /// Constructs a new encoder for all witnesses in a list of transaction inputs.
+ pub fn new(inputs: &'e [TxIn]) -> Self {
+ Self { inputs, cur_enc: inputs.first().map(|input| input.witness.encoder()) }
+ }
+}
+
+#[cfg(feature = "alloc")]
+impl encoding::Encoder for WitnessesEncoder<'_> {
+ #[inline]
+ fn current_chunk(&self) -> &[u8] {
+ self.cur_enc.as_ref().map(WitnessEncoder::current_chunk).unwrap_or_default()
+ }
+
+ #[inline]
+ fn advance(&mut self) -> EncoderStatus {
+ let Some(cur) = self.cur_enc.as_mut() else {
+ return EncoderStatus::Finished;
+ };
+
+ loop {
+ // On subsequent calls, attempt to advance the current encoder and return
+ // success if this succeeds.
+ if cur.advance().has_more() {
+ return EncoderStatus::HasMore;
+ }
+ // self.inputs guaranteed to be non-empty if cur_enc is non-None.
+ self.inputs = &self.inputs[1..];
+
+ // If advancing the current encoder failed, attempt to move to the next encoder.
+ if let Some(input) = self.inputs.first() {
+ *cur = input.witness.encoder();
+ if !cur.current_chunk().is_empty() {
+ return EncoderStatus::HasMore;
+ }
+ } else {
+ self.cur_enc = None; // shortcut the next call to advance()
+ return EncoderStatus::Finished;
+ }
+ }
+ }
+}
+
/// How many times we have state transitioned to encoding a witness (zero-based).
#[cfg(feature = "alloc")]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@@ -770,59 +823,6 @@ impl encoding::Encode for TxIn {
}
}
-/// Encodes the witnesses from a list of inputs.
-#[cfg(feature = "alloc")]
-#[derive(Debug, Clone)]
-pub struct WitnessesEncoder<'e> {
- inputs: &'e [TxIn],
- /// Encoder for the current witness being encoded.
- cur_enc: Option<WitnessEncoder<'e>>,
-}
-
-#[cfg(feature = "alloc")]
-impl<'e> WitnessesEncoder<'e> {
- /// Constructs a new encoder for all witnesses in a list of transaction inputs.
- pub fn new(inputs: &'e [TxIn]) -> Self {
- Self { inputs, cur_enc: inputs.first().map(|input| input.witness.encoder()) }
- }
-}
-
-#[cfg(feature = "alloc")]
-impl encoding::Encoder for WitnessesEncoder<'_> {
- #[inline]
- fn current_chunk(&self) -> &[u8] {
- self.cur_enc.as_ref().map(WitnessEncoder::current_chunk).unwrap_or_default()
- }
-
- #[inline]
- fn advance(&mut self) -> EncoderStatus {
- let Some(cur) = self.cur_enc.as_mut() else {
- return EncoderStatus::Finished;
- };
-
- loop {
- // On subsequent calls, attempt to advance the current encoder and return
- // success if this succeeds.
- if cur.advance().has_more() {
- return EncoderStatus::HasMore;
- }
- // self.inputs guaranteed to be non-empty if cur_enc is non-None.
- self.inputs = &self.inputs[1..];
-
- // If advancing the current encoder failed, attempt to move to the next encoder.
- if let Some(input) = self.inputs.first() {
- *cur = input.witness.encoder();
- if !cur.current_chunk().is_empty() {
- return EncoderStatus::HasMore;
- }
- } else {
- self.cur_enc = None; // shortcut the next call to advance()
- return EncoderStatus::Finished;
- }
- }
- }
-}
-
#[cfg(feature = "alloc")]
type TxInInnerDecoder = Decoder3<OutPointDecoder, ScriptSigBufDecoder, SequenceDecoder>;
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.