primitives: Move script module errors to error submodule
What changed, and why it matters
This commit is a routine code cleanup with no security relevance. It moves Bitcoin script error types into a dedicated 'error' submodule and re-exports them so the public API stays the same. There are no functional changes to how scripts are parsed, validated, or executed.
No security action required. Treat as normal refactoring/reorganization.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change relocates ScriptBufDecoderError and FromHexError from primitives/src/script/owned.rs to a new primitives/src/script/error.rs, and moves RedeemScriptSizeError/WitnessScriptSizeError re-exports through the new error module. Public re-exports are preserved in primitives/src/script/mod.rs and bitcoin/src/blockdata/script/mod.rs. The ScriptBufDecoderError struct’s visibility is adjusted from private to pub(super) for the inner ByteVecDecoderError. No logic, parsing behavior, or validation rules are modified.
Changed components
primitives/src/script/owned.rsprimitives/src/script/error.rs (new)primitives/src/script/mod.rsbitcoin/src/blockdata/script/mod.rsInspect captured patch +89 / −77
diff --git a/bitcoin/src/blockdata/script/mod.rs b/bitcoin/src/blockdata/script/mod.rs
index 5340ccde..cb798303 100644
--- a/bitcoin/src/blockdata/script/mod.rs
+++ b/bitcoin/src/blockdata/script/mod.rs
@@ -82,9 +82,9 @@ pub use self::{
pub use primitives::script::ScriptBufDecoderError;
#[doc(inline)]
pub use primitives::script::{
- RedeemScript, RedeemScriptBuf, RedeemScriptSizeError, RedeemScriptTag, Script, ScriptBuf,
- ScriptBufDecoder, ScriptEncoder, ScriptHash, ScriptHashableTag, ScriptPubKey, ScriptPubKeyBuf,
- ScriptPubKeyTag, ScriptSig, ScriptSigBuf, ScriptSigTag, SignetBlockScript,
+ error, RedeemScript, RedeemScriptBuf, RedeemScriptSizeError, RedeemScriptTag, Script,
+ ScriptBuf, ScriptBufDecoder, ScriptEncoder, ScriptHash, ScriptHashableTag, ScriptPubKey,
+ ScriptPubKeyBuf, ScriptPubKeyTag, ScriptSig, ScriptSigBuf, ScriptSigTag, SignetBlockScript,
SignetBlockScriptBuf, SignetBlockScriptTag, Tag, TapScript, TapScriptBuf, TapScriptTag,
WScriptHash, WitnessScript, WitnessScriptBuf, WitnessScriptSizeError, WitnessScriptTag,
};
diff --git a/primitives/src/script/error.rs b/primitives/src/script/error.rs
new file mode 100644
index 00000000..4db13146
--- /dev/null
+++ b/primitives/src/script/error.rs
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: CC0-1.0
+
+//! Error types for Bitcoin scripts.
+
+use core::convert::Infallible;
+use core::fmt;
+
+use encoding::ByteVecDecoderError;
+use internals::write_err;
+
+#[rustfmt::skip] // Keep public re-exports separate.
+#[doc(inline)]
+pub use crate::hash_types::{RedeemScriptSizeError, WitnessScriptSizeError};
+
+/// An error consensus decoding a `ScriptBuf<T>`.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ScriptBufDecoderError(pub(super) ByteVecDecoderError);
+
+impl From<Infallible> for ScriptBufDecoderError {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+impl fmt::Display for ScriptBufDecoderError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write_err!(f, "decoder error"; self.0) }
+}
+
+#[cfg(feature = "std")]
+impl std::error::Error for ScriptBufDecoderError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
+}
+
+/// An error parsing a script from hex.
+#[derive(Debug, Clone, PartialEq, Eq)]
+#[non_exhaustive]
+#[cfg(feature = "hex")]
+pub enum FromHexError {
+ /// Error parsing the hex input string.
+ Hex(hex::DecodeVariableLengthBytesError),
+ /// Error when decoding the script.
+ Decoder(encoding::DecodeError<ScriptBufDecoderError>),
+}
+
+#[cfg(feature = "hex")]
+impl From<Infallible> for FromHexError {
+ fn from(never: Infallible) -> Self { match never {} }
+}
+
+#[cfg(feature = "hex")]
+impl fmt::Display for FromHexError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ Self::Hex(ref e) => write_err!(f, "script hex"; e),
+ Self::Decoder(ref e) => write_err!(f, "script decoder"; e),
+ }
+ }
+}
+
+#[cfg(feature = "hex")]
+#[cfg(feature = "std")]
+impl std::error::Error for FromHexError {
+ fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match *self {
+ Self::Hex(ref e) => Some(e),
+ Self::Decoder(ref e) => Some(e),
+ }
+ }
+}
+
+#[cfg(feature = "hex")]
+impl From<hex::DecodeVariableLengthBytesError> for FromHexError {
+ fn from(e: hex::DecodeVariableLengthBytesError) -> Self { Self::Hex(e) }
+}
+
+#[cfg(feature = "hex")]
+impl From<encoding::DecodeError<ScriptBufDecoderError>> for FromHexError {
+ fn from(e: encoding::DecodeError<ScriptBufDecoderError>) -> Self { Self::Decoder(e) }
+}
diff --git a/primitives/src/script/mod.rs b/primitives/src/script/mod.rs
index b9a83da1..d61e9cb3 100644
--- a/primitives/src/script/mod.rs
+++ b/primitives/src/script/mod.rs
@@ -8,6 +8,8 @@ mod tag;
#[cfg(test)]
mod tests;
+pub mod error;
+
use core::cmp::Ordering;
use core::fmt;
#[cfg(feature = "serde")]
@@ -26,13 +28,13 @@ use crate::prelude::{Borrow, BorrowMut, Box, Cow, ToOwned, Vec};
#[doc(inline)]
pub use self::{
borrowed::{Script, ScriptEncoder},
- owned::{ScriptBuf, ScriptBufDecoder, ScriptBufDecoderError},
+ owned::{ScriptBuf, ScriptBufDecoder},
tag::{Tag, RedeemScriptTag, ScriptPubKeyTag, ScriptSigTag, SignetBlockScriptTag, TapScriptTag, WitnessScriptTag},
};
+#[doc(no_inline)]
+pub use self::error::{RedeemScriptSizeError, ScriptBufDecoderError, WitnessScriptSizeError};
#[doc(inline)]
-pub use crate::hash_types::{
- RedeemScriptSizeError, ScriptHash, WScriptHash, WitnessScriptSizeError,
-};
+pub use crate::hash_types::{ScriptHash, WScriptHash};
/// A P2SH redeem script.
pub type RedeemScriptBuf = ScriptBuf<RedeemScriptTag>;
diff --git a/primitives/src/script/owned.rs b/primitives/src/script/owned.rs
index 3feeddc5..1676854e 100644
--- a/primitives/src/script/owned.rs
+++ b/primitives/src/script/owned.rs
@@ -1,18 +1,15 @@
// SPDX-License-Identifier: CC0-1.0
-use core::convert::Infallible;
-use core::fmt;
use core::marker::PhantomData;
use core::ops::{Deref, DerefMut};
#[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured};
-use encoding::{ByteVecDecoder, ByteVecDecoderError};
-use internals::write_err;
+use encoding::ByteVecDecoder;
-use super::Script;
#[cfg(feature = "hex")]
-use crate::hex;
+use super::error::FromHexError;
+use super::{Script, ScriptBufDecoderError};
use crate::prelude::{Box, Vec};
/// An owned, growable script.
@@ -219,70 +216,6 @@ impl<T> encoding::Decodable for ScriptBuf<T> {
fn decoder() -> Self::Decoder { ScriptBufDecoder(ByteVecDecoder::new(), PhantomData) }
}
-/// An error consensus decoding a `ScriptBuf<T>`.
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct ScriptBufDecoderError(ByteVecDecoderError);
-
-impl From<Infallible> for ScriptBufDecoderError {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-impl fmt::Display for ScriptBufDecoderError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write_err!(f, "decoder error"; self.0) }
-}
-
-#[cfg(feature = "std")]
-impl std::error::Error for ScriptBufDecoderError {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
-}
-
-/// An error parsing a script from hex.
-#[derive(Debug, Clone, PartialEq, Eq)]
-#[non_exhaustive]
-#[cfg(feature = "hex")]
-pub enum FromHexError {
- /// Error parsing the hex input string.
- Hex(hex::DecodeVariableLengthBytesError),
- /// Error when decoding the script.
- Decoder(encoding::DecodeError<ScriptBufDecoderError>),
-}
-
-#[cfg(feature = "hex")]
-impl From<Infallible> for FromHexError {
- fn from(never: Infallible) -> Self { match never {} }
-}
-
-#[cfg(feature = "hex")]
-impl fmt::Display for FromHexError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- Self::Hex(ref e) => write_err!(f, "script hex"; e),
- Self::Decoder(ref e) => write_err!(f, "script decoder"; e),
- }
- }
-}
-
-#[cfg(feature = "hex")]
-#[cfg(feature = "std")]
-impl std::error::Error for FromHexError {
- fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
- match *self {
- Self::Hex(ref e) => Some(e),
- Self::Decoder(ref e) => Some(e),
- }
- }
-}
-
-#[cfg(feature = "hex")]
-impl From<hex::DecodeVariableLengthBytesError> for FromHexError {
- fn from(e: hex::DecodeVariableLengthBytesError) -> Self { Self::Hex(e) }
-}
-
-#[cfg(feature = "hex")]
-impl From<encoding::DecodeError<ScriptBufDecoderError>> for FromHexError {
- fn from(e: encoding::DecodeError<ScriptBufDecoderError>) -> Self { Self::Decoder(e) }
-}
-
#[cfg(feature = "arbitrary")]
impl<'a, T> Arbitrary<'a> for ScriptBuf<T> {
#[inline]
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.