Merge rust-bitcoin/rust-bitcoin#3200: hashes: Fix a bunch of bugs caused by broken CI script

009e747323 CI: Put fuzz last in CRATES list (Tobin C. Harding)
aed61bd2d4 Implement FromStr and serde impls for siphash (Tobin C. Harding)
f8846101ae siphash: Make functions inherent (Tobin C. Harding)
321d82ca53 hashes: Pin in extra_test (Tobin C. Harding)
42c7617a46 Fix shchemars test (Tobin C. Harding)
b6fda6517c Implement JsonSchema for siphash::Hash (Tobin C. Harding)
1af6ff4394 hashes: Feature gate hash_reader unit test (Tobin C. Harding)
5230d3309c Remove hash_reader from sha256t_hash_newtype (Tobin C. Harding)

Pull request description:

  This is just the bug fixes pulled out of #2861

  The root problem here is the bug described in https://github.com/rust-bitcoin/rust-bitcoin-maintainer-tools/issues/10

  This PR works around the bug by putting `fuzz` last in the list.

ACKs for top commit:
  apoelstra:
    ACK 009e74732321f9f3e6d09e158dd577a7d9ebca35; confirmed that local CI STILL does not pass after this; needs #3195 as well; but it is improved
  Kixunil:
    ACK 009e747323 but I'd much rather see the siphash problems addressed by splitting up the macro. I can make a PR for that (but just that) later.

Tree-SHA512: f724570003b862e994787192b720c4698e6b904ececa7188770ee507dd9e12382ae64db3363fa15ab3f347341c99ed9a75938f4da0438ce3a0fa88717497a233
This commit is contained in:
merge-script 2024-08-22 13:30:26 +00:00
commit fda76d9f62
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
7 changed files with 59 additions and 22 deletions

View File

@ -5,4 +5,4 @@
# shellcheck disable=SC2034
# Crates in this workspace to test (note "fuzz" is only built not tested).
CRATES=("addresses" "base58" "bitcoin" "fuzz" "hashes" "internals" "io" "units")
CRATES=("addresses" "base58" "bitcoin" "hashes" "internals" "io" "units" "fuzz")

View File

@ -5,5 +5,12 @@ set -euox pipefail
REPO_DIR=$(git rev-parse --show-toplevel)
pushd "$REPO_DIR/hashes/extended_tests/schemars" > /dev/null
# This comment mentions Rust 1.63 to assist grepping when doing MSRV update.
#
if cargo --version | grep -q '1\.63'; then
cargo update -p regex --precise 1.7.3
fi
cargo test
popd > /dev/null

View File

@ -4,10 +4,6 @@ Run as usual with `cargo test`.
## Minimum Supported Rust Version (MSRV)
To run the tests with the MSRV you will need to pin `serde`:
```bash
cargo update -p serde --precise 1.0.156
cargo update -p regex --precise 1.7.3
cargo update -p chrono --precise 0.4.24
```
To run the tests with the current MSRV you will need to pin some
dependencies. See the `hashes/contrib/extra_tests.sh` script for the
current list of pins.

View File

@ -2,6 +2,7 @@ fn main() {}
#[cfg(test)]
mod tests {
use bitcoin_hashes::*;
use bitcoin_hashes::sha256::Midstate;
#[test]
fn hash160() {
@ -117,6 +118,9 @@ mod tests {
147, 108, 71, 99, 110, 96, 125, 179, 62, 234, 221, 198, 240, 201,
];
// The midstate of an empty hash engine tagged with "TapLeaf".
const TAP_LEAF_MIDSTATE: Midstate = Midstate::new(TEST_MIDSTATE, 64);
#[derive(
Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Hash, schemars::JsonSchema,
)]
@ -124,9 +128,7 @@ mod tests {
impl sha256t::Tag for TestHashTag {
fn engine() -> sha256::HashEngine {
// The TapRoot TapLeaf midstate.
let midstate = sha256::Midstate::from_byte_array(TEST_MIDSTATE);
sha256::HashEngine::from_midstate(midstate, 64)
sha256::HashEngine::from_midstate(TAP_LEAF_MIDSTATE)
}
}

View File

@ -324,7 +324,7 @@ impl std::error::Error for FromSliceError {}
#[cfg(test)]
mod tests {
use super::*;
use crate::{sha256, sha256d};
use crate::sha256d;
hash_newtype! {
/// A test newtype
@ -351,7 +351,10 @@ mod tests {
}
#[test]
#[cfg(feature = "bitcoin-io")]
fn hash_reader() {
use crate::sha256;
let mut reader: &[u8] = b"hello";
assert_eq!(sha256::Hash::hash_reader(&mut reader).unwrap(), sha256::Hash::hash(b"hello"),)
}

View File

@ -240,13 +240,6 @@ macro_rules! sha256t_hash_newtype {
{
<$hash_name as $crate::GeneralHash>::hash_byte_chunks(byte_slices)
}
/// Hashes the entire contents of the `reader`.
#[cfg(feature = "bitcoin-io")]
#[allow(unused)] // the user of macro may not need this
fn hash_reader<R: io::BufRead>(reader: &mut R) -> Result<Self, io::Error> {
<$hash_name as $crate::GeneralHash>::hash_reader(reader)
}
}
impl $crate::GeneralHash for $hash_name {

View File

@ -4,8 +4,11 @@
use core::ops::Index;
use core::slice::SliceIndex;
use core::str::FromStr;
use core::{cmp, mem, ptr};
use hex::FromHex;
use crate::internal_macros::arr_newtype_fmt_impl;
use crate::HashEngine as _;
@ -14,6 +17,21 @@ use crate::HashEngine as _;
#[repr(transparent)]
pub struct Hash([u8; 8]);
#[cfg(feature = "schemars")]
impl schemars::JsonSchema for Hash {
fn schema_name() -> String { "Hash".to_owned() }
fn json_schema(gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
let mut schema: schemars::schema::SchemaObject = <String>::json_schema(gen).into();
schema.string = Some(Box::new(schemars::schema::StringValidation {
max_length: Some(8 * 2),
min_length: Some(8 * 2),
pattern: Some("[0-9a-fA-F]+".to_owned()),
}));
schema.into()
}
}
#[cfg(not(hashes_fuzz))]
fn from_engine(e: HashEngine) -> Hash { Hash::from_u64(Hash::from_engine_to_u64(e)) }
@ -211,6 +229,15 @@ impl Hash {
/// Creates a hash from its (little endian) 64-bit integer representation.
pub fn from_u64(hash: u64) -> Hash { Hash(hash.to_le_bytes()) }
/// Returns the underlying byte array.
pub const fn to_byte_array(self) -> [u8; 8] { self.0 }
/// Returns a reference to the underlying byte array.
pub const fn as_byte_array(&self) -> &[u8; 8] { &self.0 }
/// Constructs a hash from the underlying byte array.
pub const fn from_byte_array(bytes: [u8; 8]) -> Self { Self(bytes) }
fn from_slice(sl: &[u8]) -> Result<Self, crate::FromSliceError> {
let mut ret = [0; 8];
ret.copy_from_slice(sl);
@ -226,11 +253,11 @@ impl crate::Hash for Hash {
fn from_slice(sl: &[u8]) -> Result<Self, crate::FromSliceError> { Self::from_slice(sl) }
fn to_byte_array(self) -> Self::Bytes { self.0 }
fn to_byte_array(self) -> Self::Bytes { self.to_byte_array() }
fn as_byte_array(&self) -> &Self::Bytes { &self.0 }
fn as_byte_array(&self) -> &Self::Bytes { self.as_byte_array() }
fn from_byte_array(bytes: Self::Bytes) -> Self { Hash(bytes) }
fn from_byte_array(bytes: Self::Bytes) -> Self { Self::from_byte_array(bytes) }
}
impl<I: SliceIndex<[u8]>> Index<I> for Hash {
@ -240,7 +267,16 @@ impl<I: SliceIndex<[u8]>> Index<I> for Hash {
fn index(&self, index: I) -> &Self::Output { &self.0[index] }
}
impl FromStr for Hash {
type Err = hex::HexToArrayError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let bytes = <[u8; 8]>::from_hex(s)?;
Ok(Self::from_byte_array(bytes))
}
}
arr_newtype_fmt_impl!(Hash, 8);
serde_impl!(Hash, 8);
borrow_slice_impl!(Hash);
/// Load an u64 using up to 7 bytes of a byte slice.