primitives: Move witness module errors to error submodule
What changed, and why it matters
This commit is a simple internal code reorganization. It moves two error types (WitnessDecoderError and UnexpectedEofError) from the main witness module into a new error submodule and re-exports them so existing code keeps working. There is no functional change to how witness data is decoded or validated.
No security action needed. Treat as routine refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors primitives/src/witness.rs and bitcoin/src/blockdata/witness.rs. It creates a new pub mod error in primitives/src/witness.rs, relocates WitnessDecoderError, WitnessDecoderErrorInner, UnexpectedEofError, and their trait implementations there, and changes visibility of the inner fields from private to pub(super). The bitcoin crate re-exports the new error submodule. No logic, parsing, serialization, or validation behavior is altered.
Changed components
primitives/src/witness.rsbitcoin/src/blockdata/witness.rsInspect captured patch +78 / −64
diff --git a/bitcoin/src/blockdata/witness.rs b/bitcoin/src/blockdata/witness.rs
index 93d5395f..50522827 100644
--- a/bitcoin/src/blockdata/witness.rs
+++ b/bitcoin/src/blockdata/witness.rs
@@ -17,7 +17,7 @@ type BorrowedControlBlock<'a> = ControlBlock<&'a TaprootMerkleBranch, &'a Serial
#[rustfmt::skip] // Keep public re-exports separate.
#[doc(inline)]
-pub use primitives::witness::{Iter, Witness, WitnessDecoder, WitnessEncoder};
+pub use primitives::witness::{error, Iter, Witness, WitnessDecoder, WitnessEncoder};
#[doc(no_inline)]
pub use primitives::witness::{UnexpectedEofError, WitnessDecoderError};
diff --git a/primitives/src/witness.rs b/primitives/src/witness.rs
index d94fd3ea..faf50b31 100644
--- a/primitives/src/witness.rs
+++ b/primitives/src/witness.rs
@@ -4,7 +4,6 @@
//!
//! This module contains the [`Witness`] struct and related methods to operate on it
-use core::convert::Infallible;
use core::fmt;
use core::ops::Index;
@@ -13,19 +12,23 @@ use arbitrary::{Arbitrary, Unstructured};
#[cfg(doc)]
use encoding::Decoder4;
use encoding::{
- self, BytesEncoder, CompactSizeDecoder, CompactSizeDecoderError, CompactSizeEncoder,
- Decoder as _, Encoder2,
+ self, BytesEncoder, CompactSizeDecoder, CompactSizeEncoder, Decoder as _, Encoder2,
};
#[cfg(feature = "hex")]
use hex::DecodeVariableLengthBytesError;
use internals::slice::SliceExt;
use internals::wrap_debug::WrapDebug;
-use internals::write_err;
use crate::prelude::{Box, Vec};
#[cfg(doc)]
use crate::TxIn;
+#[rustfmt::skip] // Keep public re-exports separate.
+#[doc(no_inline)]
+pub use self::error::{UnexpectedEofError, WitnessDecoderError};
+
+use self::error::WitnessDecoderErrorInner;
+
/// Maximum amount of memory (in bytes) to allocate at once when deserializing vectors.
#[cfg(feature = "alloc")]
const MAX_VECTOR_ALLOCATE: usize = 1_000_000;
@@ -822,65 +825,6 @@ impl Default for Witness {
fn default() -> Self { Self::new() }
}
-/// An error when consensus decoding a [`Witness`].
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct WitnessDecoderError(WitnessDecoderErrorInner);
-
-#[derive(Debug, Clone, PartialEq, Eq)]
-enum WitnessDecoderErrorInner {
- /// Error decoding the vector length prefix.
- LengthPrefixDecode(CompactSizeDecoderError),
- /// Not enough bytes given to decoder.
- UnexpectedEof(UnexpectedEofError),
-}
-
-impl From<Infallible> for WitnessDecoderError {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-impl fmt::Display for WitnessDecoderError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- use WitnessDecoderErrorInner as E;
-
- match self.0 {
- E::LengthPrefixDecode(ref e) => write_err!(f, "vec decoder error"; e),
- E::UnexpectedEof(ref e) => write_err!(f, "decoder error"; e),
- }
- }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for WitnessDecoderError {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- use WitnessDecoderErrorInner as E;
-
- match self.0 {
- E::LengthPrefixDecode(ref e) => Some(e),
- E::UnexpectedEof(ref e) => Some(e),
- }
- }
-}
-
-/// Not enough witness elements (bytes) given to decoder.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct UnexpectedEofError {
- /// Number of elements missing to complete decoder.
- missing_elements: usize,
-}
-
-impl From<Infallible> for UnexpectedEofError {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-impl fmt::Display for UnexpectedEofError {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(f, "not enough witness elements for decoder, missing {}", self.missing_elements)
- }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for UnexpectedEofError {}
-
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for Witness {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
@@ -968,6 +912,76 @@ fn decode_unchecked(slice: &mut &[u8]) -> u64 {
}
}
+/// Error types for witness data.
+pub mod error {
+ use core::convert::Infallible;
+ use core::fmt;
+
+ use encoding::CompactSizeDecoderError;
+ use internals::write_err;
+
+ /// An error when consensus decoding a [`Witness`].
+ ///
+ /// [`Witness`]: super::Witness
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ pub struct WitnessDecoderError(pub(super) WitnessDecoderErrorInner);
+
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ pub(super) enum WitnessDecoderErrorInner {
+ /// Error decoding the vector length prefix.
+ LengthPrefixDecode(CompactSizeDecoderError),
+ /// Not enough bytes given to decoder.
+ UnexpectedEof(UnexpectedEofError),
+ }
+
+ impl From<Infallible> for WitnessDecoderError {
+ fn from(never: Infallible) -> Self { match never {} }
+ }
+
+ impl fmt::Display for WitnessDecoderError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ use WitnessDecoderErrorInner as E;
+
+ match self.0 {
+ E::LengthPrefixDecode(ref e) => write_err!(f, "vec decoder error"; e),
+ E::UnexpectedEof(ref e) => write_err!(f, "decoder error"; e),
+ }
+ }
+ }
+
+ #[cfg(feature = "std")]
+ impl std::error::Error for WitnessDecoderError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ use WitnessDecoderErrorInner as E;
+
+ match self.0 {
+ E::LengthPrefixDecode(ref e) => Some(e),
+ E::UnexpectedEof(ref e) => Some(e),
+ }
+ }
+ }
+
+ /// Not enough witness elements (bytes) given to decoder.
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ pub struct UnexpectedEofError {
+ /// Number of elements missing to complete decoder.
+ pub(super) missing_elements: usize,
+ }
+
+ impl From<Infallible> for UnexpectedEofError {
+ fn from(never: Infallible) -> Self { match never {} }
+ }
+
+ impl fmt::Display for UnexpectedEofError {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "not enough witness elements for decoder, missing {}", self.missing_elements)
+ }
+ }
+
+ #[cfg(feature = "std")]
+ impl std::error::Error for UnexpectedEofError {}
+}
+
#[cfg(test)]
mod test {
#[cfg(feature = "alloc")]
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.