Merge rust-bitcoin/rust-bitcoin#1873: Improve `hashes::Error`

06afd52a12 Improve hashes::Error (Tobin C. Harding)

Pull request description:

  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`.

ACKs for top commit:
  apoelstra:
    ACK 06afd52a12
  Kixunil:
    ACK 06afd52a12

Tree-SHA512: 20a517daaf3e9e09744e2a65cde6e238c8f2d1224899a6c04142a3a4e635d54112b0a2e846d25256071bb27cb70f7482380f98e9a535a5498aa4c7dc0d52cc54
This commit is contained in:
Andrew Poelstra 2023-05-29 21:51:17 +00:00
commit 80efdb065a
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
17 changed files with 45 additions and 60 deletions

View File

@ -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<hashes::Error> for Error {
fn from(e: hashes::Error) -> Error { Error::HashParse(e) }
impl From<hashes::FromSliceError> for Error {
fn from(e: hashes::FromSliceError) -> Error { Error::HashParse(e) }
}
impl From<encode::Error> for Error {

View File

@ -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

View File

@ -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,
}
}
}

View File

@ -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,

View File

@ -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<T: Hash> Hash for Hmac<T> {
const LEN: usize = T::LEN;
fn from_slice(sl: &[u8]) -> Result<Hmac<T>, Error> { T::from_slice(sl).map(Hmac) }
fn from_slice(sl: &[u8]) -> Result<Hmac<T>, FromSliceError> { T::from_slice(sl).map(Hmac) }
fn to_byte_array(self) -> Self::Bytes { self.0.to_byte_array() }

View File

@ -151,9 +151,9 @@ macro_rules! hash_trait_impls {
from_engine(e)
}
fn from_slice(sl: &[u8]) -> Result<Hash<$($gen),*>, Error> {
fn from_slice(sl: &[u8]) -> Result<Hash<$($gen),*>, 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);

View File

@ -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<Self, Error>;
fn from_slice(sl: &[u8]) -> Result<Self, FromSliceError>;
/// 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};

View File

@ -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,

View File

@ -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<ValueT>(PhantomData<ValueT>);
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<Self, Error>;
fn from_slice_delegated(sl: &[u8]) -> Result<Self, FromSliceError>;
/// Do serde serialization.
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
@ -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<Self, $crate::Error> {
fn from_slice_delegated(sl: &[u8]) -> Result<Self, $crate::FromSliceError> {
#[allow(unused_imports)]
use $crate::Hash as _;
$t::from_slice(sl)

View File

@ -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,

View File

@ -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<Midstate, Error> {
pub fn from_slice(sl: &[u8]) -> Result<Midstate, FromSliceError> {
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);

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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.
///

View File

@ -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,

View File

@ -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)?))
}