From 06afd52a12b74a600747d1563786fbf53cd37018 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Wed, 24 May 2023 13:29:30 +1000 Subject: [PATCH] Improve hashes::Error We are trying to make error types stable on the way to v1.0 The current `hashes::Error` is a "general" enum error type with a single variant, better to use a struct and make the error usecase specific. Improve the `hashes::Error` by doing: - Make it a struct - Rename to `FromSliceError` - Move it to the crate root (remove `error` module) Includes usage in `bitcoin`. --- bitcoin/src/psbt/error.rs | 6 +++--- hashes/CHANGELOG.md | 4 ++++ hashes/src/error.rs | 35 ----------------------------------- hashes/src/hash160.rs | 2 +- hashes/src/hmac.rs | 4 ++-- hashes/src/internal_macros.rs | 4 ++-- hashes/src/lib.rs | 22 +++++++++++++++++++--- hashes/src/ripemd160.rs | 2 +- hashes/src/serde_macros.rs | 6 +++--- hashes/src/sha1.rs | 2 +- hashes/src/sha256.rs | 6 +++--- hashes/src/sha256d.rs | 2 +- hashes/src/sha256t.rs | 2 +- hashes/src/sha512.rs | 2 +- hashes/src/sha512_256.rs | 2 +- hashes/src/siphash24.rs | 2 +- hashes/src/util.rs | 2 +- 17 files changed, 45 insertions(+), 60 deletions(-) delete mode 100644 hashes/src/error.rs diff --git a/bitcoin/src/psbt/error.rs b/bitcoin/src/psbt/error.rs index e55c2c4e..778086b8 100644 --- a/bitcoin/src/psbt/error.rs +++ b/bitcoin/src/psbt/error.rs @@ -57,7 +57,7 @@ pub enum Error { /// Unable to parse as a standard sighash type. NonStandardSighashType(u32), /// Parsing errors from bitcoin_hashes - HashParse(hashes::Error), + HashParse(hashes::FromSliceError), /// The pre-image must hash to the correponding psbt hash InvalidPreimageHashPair { /// Hash-type @@ -204,8 +204,8 @@ impl std::error::Error for Error { } #[doc(hidden)] -impl From for Error { - fn from(e: hashes::Error) -> Error { Error::HashParse(e) } +impl From for Error { + fn from(e: hashes::FromSliceError) -> Error { Error::HashParse(e) } } impl From for Error { diff --git a/hashes/CHANGELOG.md b/hashes/CHANGELOG.md index 689ade55..2eae01c3 100644 --- a/hashes/CHANGELOG.md +++ b/hashes/CHANGELOG.md @@ -1,3 +1,7 @@ +# Unreleased + +* Convert enum `crate::Error` to struct `crate::FromSliceError`. + # 0.12.0 - 2023-03-05 0.12 is a significant release. We pulled the repository into the rust-bitcoin diff --git a/hashes/src/error.rs b/hashes/src/error.rs deleted file mode 100644 index 79108887..00000000 --- a/hashes/src/error.rs +++ /dev/null @@ -1,35 +0,0 @@ -// SPDX-License-Identifier: CC0-1.0 - -//! Crate error type. -//! - -use core::fmt; - -/// Crate error type. -#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub enum Error { - /// Tried to create a fixed-length hash from a slice with the wrong size (expected, got). - InvalidLength(usize, usize), -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use self::Error::*; - - match self { - InvalidLength(ref ell, ref ell2) => - write!(f, "invalid slice length {} (expected {})", ell2, ell), - } - } -} - -#[cfg(feature = "std")] -impl std::error::Error for Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::Error::*; - - match self { - InvalidLength(_, _) => None, - } - } -} diff --git a/hashes/src/hash160.rs b/hashes/src/hash160.rs index 66d30b86..af44f477 100644 --- a/hashes/src/hash160.rs +++ b/hashes/src/hash160.rs @@ -12,7 +12,7 @@ use core::ops::Index; use core::slice::SliceIndex; use core::str; -use crate::{ripemd160, sha256, Error}; +use crate::{ripemd160, sha256, FromSliceError}; crate::internal_macros::hash_type! { 160, diff --git a/hashes/src/hmac.rs b/hashes/src/hmac.rs index 425eb1d0..32ca96a1 100644 --- a/hashes/src/hmac.rs +++ b/hashes/src/hmac.rs @@ -13,7 +13,7 @@ use core::{borrow, fmt, ops, str}; #[cfg(feature = "serde")] use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use crate::{Error, Hash, HashEngine}; +use crate::{FromSliceError, Hash, HashEngine}; /// A hash computed from a RFC 2104 HMAC. Parameterized by the underlying hash function. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -157,7 +157,7 @@ impl Hash for Hmac { const LEN: usize = T::LEN; - fn from_slice(sl: &[u8]) -> Result, Error> { T::from_slice(sl).map(Hmac) } + fn from_slice(sl: &[u8]) -> Result, FromSliceError> { T::from_slice(sl).map(Hmac) } fn to_byte_array(self) -> Self::Bytes { self.0.to_byte_array() } diff --git a/hashes/src/internal_macros.rs b/hashes/src/internal_macros.rs index 660ccf61..13ef0be1 100644 --- a/hashes/src/internal_macros.rs +++ b/hashes/src/internal_macros.rs @@ -151,9 +151,9 @@ macro_rules! hash_trait_impls { from_engine(e) } - fn from_slice(sl: &[u8]) -> Result, Error> { + fn from_slice(sl: &[u8]) -> Result, FromSliceError> { if sl.len() != $bits / 8 { - Err(Error::InvalidLength(Self::LEN, sl.len())) + Err(FromSliceError{expected: Self::LEN, got: sl.len()}) } else { let mut ret = [0; $bits / 8]; ret.copy_from_slice(sl); diff --git a/hashes/src/lib.rs b/hashes/src/lib.rs index 69f66564..b54feb2d 100644 --- a/hashes/src/lib.rs +++ b/hashes/src/lib.rs @@ -112,7 +112,6 @@ mod util; #[macro_use] pub mod serde_macros; pub mod cmp; -pub mod error; pub mod hash160; pub mod hex; pub mod hmac; @@ -129,7 +128,6 @@ pub mod siphash24; use core::{borrow, fmt, hash, ops}; -pub use error::Error; pub use hmac::{Hmac, HmacEngine}; /// A hashing engine which bytes can be serialized into. @@ -188,7 +186,7 @@ pub trait Hash: const LEN: usize; /// Copies a byte slice into a hash object. - fn from_slice(sl: &[u8]) -> Result; + fn from_slice(sl: &[u8]) -> Result; /// Hashes some bytes. fn hash(data: &[u8]) -> Self { @@ -219,6 +217,24 @@ pub trait Hash: fn all_zeros() -> Self; } +/// Attempted to create a hash from an invalid length slice. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct FromSliceError { + expected: usize, + got: usize, +} + +impl fmt::Display for FromSliceError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "invalid slice length {} (expected {})", self.got, self.expected) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for FromSliceError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } +} + #[cfg(test)] mod tests { use crate::{sha256d, Hash}; diff --git a/hashes/src/ripemd160.rs b/hashes/src/ripemd160.rs index bc25b8dd..f3b306a1 100644 --- a/hashes/src/ripemd160.rs +++ b/hashes/src/ripemd160.rs @@ -8,7 +8,7 @@ use core::ops::Index; use core::slice::SliceIndex; use core::{cmp, str}; -use crate::{Error, HashEngine as _}; +use crate::{FromSliceError, HashEngine as _}; crate::internal_macros::hash_type! { 160, diff --git a/hashes/src/serde_macros.rs b/hashes/src/serde_macros.rs index 223ef538..ce7b924f 100644 --- a/hashes/src/serde_macros.rs +++ b/hashes/src/serde_macros.rs @@ -10,7 +10,7 @@ pub mod serde_details { use core::str::FromStr; use core::{fmt, ops, str}; - use crate::Error; + use crate::FromSliceError; struct HexVisitor(PhantomData); use serde::{de, Deserializer, Serializer}; @@ -82,7 +82,7 @@ pub mod serde_details { const N: usize; /// Helper function to turn a deserialized slice into the correct hash type. - fn from_slice_delegated(sl: &[u8]) -> Result; + fn from_slice_delegated(sl: &[u8]) -> Result; /// Do serde serialization. fn serialize(&self, s: S) -> Result { @@ -112,7 +112,7 @@ macro_rules! serde_impl( ($t:ident, $len:expr $(, $gen:ident: $gent:ident)*) => ( impl<$($gen: $gent),*> $crate::serde_macros::serde_details::SerdeHash for $t<$($gen),*> { const N : usize = $len; - fn from_slice_delegated(sl: &[u8]) -> Result { + fn from_slice_delegated(sl: &[u8]) -> Result { #[allow(unused_imports)] use $crate::Hash as _; $t::from_slice(sl) diff --git a/hashes/src/sha1.rs b/hashes/src/sha1.rs index e033ef60..a638ebc3 100644 --- a/hashes/src/sha1.rs +++ b/hashes/src/sha1.rs @@ -8,7 +8,7 @@ use core::ops::Index; use core::slice::SliceIndex; use core::{cmp, str}; -use crate::{Error, HashEngine as _}; +use crate::{FromSliceError, HashEngine as _}; crate::internal_macros::hash_type! { 160, diff --git a/hashes/src/sha256.rs b/hashes/src/sha256.rs index 6f800207..e34e3646 100644 --- a/hashes/src/sha256.rs +++ b/hashes/src/sha256.rs @@ -8,7 +8,7 @@ use core::ops::Index; use core::slice::SliceIndex; use core::{cmp, str}; -use crate::{hex, sha256d, Error, HashEngine as _}; +use crate::{hex, sha256d, FromSliceError, HashEngine as _}; crate::internal_macros::hash_type! { 256, @@ -142,9 +142,9 @@ impl Midstate { pub const fn from_byte_array(inner: [u8; 32]) -> Self { Midstate(inner) } /// Copies a byte slice into the [`Midstate`] object. - pub fn from_slice(sl: &[u8]) -> Result { + pub fn from_slice(sl: &[u8]) -> Result { if sl.len() != Self::LEN { - Err(Error::InvalidLength(Self::LEN, sl.len())) + Err(FromSliceError { expected: Self::LEN, got: sl.len() }) } else { let mut ret = [0; 32]; ret.copy_from_slice(sl); diff --git a/hashes/src/sha256d.rs b/hashes/src/sha256d.rs index 427a46a3..86cff70a 100644 --- a/hashes/src/sha256d.rs +++ b/hashes/src/sha256d.rs @@ -7,7 +7,7 @@ use core::ops::Index; use core::slice::SliceIndex; use core::str; -use crate::{sha256, Error}; +use crate::{sha256, FromSliceError}; crate::internal_macros::hash_type! { 256, diff --git a/hashes/src/sha256t.rs b/hashes/src/sha256t.rs index 8d802415..6b94dfc8 100644 --- a/hashes/src/sha256t.rs +++ b/hashes/src/sha256t.rs @@ -8,7 +8,7 @@ use core::ops::Index; use core::slice::SliceIndex; use core::{cmp, str}; -use crate::{sha256, Error}; +use crate::{sha256, FromSliceError}; type HashEngine = sha256::HashEngine; diff --git a/hashes/src/sha512.rs b/hashes/src/sha512.rs index 39b75e89..58877c92 100644 --- a/hashes/src/sha512.rs +++ b/hashes/src/sha512.rs @@ -8,7 +8,7 @@ use core::ops::Index; use core::slice::SliceIndex; use core::{cmp, str}; -use crate::{Error, HashEngine as _}; +use crate::{FromSliceError, HashEngine as _}; crate::internal_macros::hash_trait_impls!(512, false); diff --git a/hashes/src/sha512_256.rs b/hashes/src/sha512_256.rs index 664eece3..6bef7bec 100644 --- a/hashes/src/sha512_256.rs +++ b/hashes/src/sha512_256.rs @@ -12,7 +12,7 @@ use core::slice::SliceIndex; use core::str; use crate::sha512::BLOCK_SIZE; -use crate::{sha512, Error}; +use crate::{sha512, FromSliceError}; /// Engine to compute SHA512/256 hash function. /// diff --git a/hashes/src/siphash24.rs b/hashes/src/siphash24.rs index 6eead542..86981afe 100644 --- a/hashes/src/siphash24.rs +++ b/hashes/src/siphash24.rs @@ -7,7 +7,7 @@ use core::ops::Index; use core::slice::SliceIndex; use core::{cmp, mem, ptr, str}; -use crate::{Error, Hash as _, HashEngine as _}; +use crate::{FromSliceError, Hash as _, HashEngine as _}; crate::internal_macros::hash_type! { 64, diff --git a/hashes/src/util.rs b/hashes/src/util.rs index cf6729a6..39eb33b6 100644 --- a/hashes/src/util.rs +++ b/hashes/src/util.rs @@ -241,7 +241,7 @@ macro_rules! hash_newtype { } #[inline] - fn from_slice(sl: &[u8]) -> Result<$newtype, $crate::Error> { + fn from_slice(sl: &[u8]) -> Result<$newtype, $crate::FromSliceError> { Ok($newtype(<$hash as $crate::Hash>::from_slice(sl)?)) }