Skip to content

Commit b4fc7f6

Browse files
committed
cosmwasm_std: remove dependency on DefaultHasher in tests
DefaultHasher is part of std module and is not available on no_std builds. Remove dependency on that type to pave the path for no_std support. This is done by adding test_utils::check_hash_impl helper function which tests whether type implements Hash trait. That function uses crc32fast::Hasher instead of DefaultHasher thus eliminating need for std. Furthermore, Binary and HexBinary tests checking AsRef implementation call AsRef::as_ref directly and explicitly check the result rather than unnecessarily hashing the data. As an added bonus, this diff has negative delta. \o/
1 parent 0dae968 commit b4fc7f6

File tree

7 files changed

+44
-102
lines changed

7 files changed

+44
-102
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/std/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,6 @@ cosmwasm-crypto = { path = "../crypto", version = "1.3.0-rc.0" }
6363
cosmwasm-schema = { path = "../schema" }
6464
# The chrono dependency is only used in an example, which Rust compiles for us. If this causes trouble, remove it.
6565
chrono = { version = "0.4", default-features = false, features = ["alloc", "std"] }
66+
crc32fast = "1.3.2"
6667
hex-literal = "0.3.1"
6768
serde_json = "1.0.81"

packages/std/src/addresses.rs

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -401,9 +401,7 @@ mod tests {
401401
use super::*;
402402
use crate::HexBinary;
403403
use hex_literal::hex;
404-
use std::collections::hash_map::DefaultHasher;
405404
use std::collections::HashSet;
406-
use std::hash::{Hash, Hasher};
407405

408406
#[test]
409407
fn addr_unchecked_works() {
@@ -651,23 +649,9 @@ mod tests {
651649

652650
#[test]
653651
fn canonical_addr_implements_hash() {
654-
let alice1 = CanonicalAddr::from([0, 187, 61, 11, 250, 0]);
655-
let mut hasher = DefaultHasher::new();
656-
alice1.hash(&mut hasher);
657-
let alice1_hash = hasher.finish();
658-
659-
let alice2 = CanonicalAddr::from([0, 187, 61, 11, 250, 0]);
660-
let mut hasher = DefaultHasher::new();
661-
alice2.hash(&mut hasher);
662-
let alice2_hash = hasher.finish();
663-
652+
let alice = CanonicalAddr::from([0, 187, 61, 11, 250, 0]);
664653
let bob = CanonicalAddr::from([16, 21, 33, 0, 255, 9]);
665-
let mut hasher = DefaultHasher::new();
666-
bob.hash(&mut hasher);
667-
let bob_hash = hasher.finish();
668-
669-
assert_eq!(alice1_hash, alice2_hash);
670-
assert_ne!(alice1_hash, bob_hash);
654+
crate::test_utils::check_hash_impl(alice, bob)
671655
}
672656

673657
/// This requires Hash and Eq to be implemented

packages/std/src/binary.rs

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,7 @@ mod tests {
240240
use super::*;
241241
use crate::errors::StdError;
242242
use crate::serde::{from_slice, to_vec};
243-
use std::collections::hash_map::DefaultHasher;
244243
use std::collections::HashSet;
245-
use std::hash::{Hash, Hasher};
246244

247245
#[test]
248246
fn encode_decode() {
@@ -505,51 +503,17 @@ mod tests {
505503

506504
#[test]
507505
fn binary_implements_as_ref() {
508-
// Can use as_ref (this we already get via the Deref implementation)
509-
let data = Binary(vec![7u8, 35, 49, 101, 0, 255]);
510-
assert_eq!(data.as_ref(), &[7u8, 35, 49, 101, 0, 255]);
511-
512-
let data = Binary(vec![7u8, 35, 49, 101, 0, 255]);
513-
let data_ref = &data;
514-
assert_eq!(data_ref.as_ref(), &[7u8, 35, 49, 101, 0, 255]);
515-
516-
// Implements as ref
517-
518-
// This is a dummy function to mimic the signature of
519-
// https://docs.rs/sha2/0.10.6/sha2/trait.Digest.html#tymethod.digest
520-
fn hash(data: impl AsRef<[u8]>) -> u64 {
521-
let mut hasher = DefaultHasher::new();
522-
data.as_ref().hash(&mut hasher);
523-
hasher.finish()
524-
}
525-
526-
let data = Binary(vec![7u8, 35, 49, 101, 0, 255]);
527-
hash(data);
528-
529-
let data = Binary(vec![7u8, 35, 49, 101, 0, 255]);
530-
let data_ref = &data;
531-
hash(data_ref);
506+
let want = &[7u8, 35, 49, 101, 0, 255];
507+
let data = Binary(want.to_vec());
508+
assert_eq!(want, AsRef::<[u8]>::as_ref(&data));
509+
assert_eq!(want, AsRef::<[u8]>::as_ref(&&data));
532510
}
533511

534512
#[test]
535513
fn binary_implements_hash() {
536-
let a1 = Binary::from([0, 187, 61, 11, 250, 0]);
537-
let mut hasher = DefaultHasher::new();
538-
a1.hash(&mut hasher);
539-
let a1_hash = hasher.finish();
540-
541-
let a2 = Binary::from([0, 187, 61, 11, 250, 0]);
542-
let mut hasher = DefaultHasher::new();
543-
a2.hash(&mut hasher);
544-
let a2_hash = hasher.finish();
545-
514+
let a = Binary::from([0, 187, 61, 11, 250, 0]);
546515
let b = Binary::from([16, 21, 33, 0, 255, 9]);
547-
let mut hasher = DefaultHasher::new();
548-
b.hash(&mut hasher);
549-
let b_hash = hasher.finish();
550-
551-
assert_eq!(a1_hash, a2_hash);
552-
assert_ne!(a1_hash, b_hash);
516+
crate::test_utils::check_hash_impl(a, b)
553517
}
554518

555519
/// This requires Hash and Eq to be implemented

packages/std/src/hex_binary.rs

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,7 @@ mod tests {
248248
use super::*;
249249

250250
use crate::{from_slice, to_vec, StdError};
251-
use std::collections::hash_map::DefaultHasher;
252251
use std::collections::HashSet;
253-
use std::hash::{Hash, Hasher};
254252

255253
#[test]
256254
fn from_hex_works() {
@@ -569,51 +567,17 @@ mod tests {
569567

570568
#[test]
571569
fn hex_binary_implements_as_ref() {
572-
// Can use as_ref (this we already get via the Deref implementation)
573-
let data = HexBinary(vec![7u8, 35, 49, 101, 0, 255]);
574-
assert_eq!(data.as_ref(), &[7u8, 35, 49, 101, 0, 255]);
575-
576-
let data = HexBinary(vec![7u8, 35, 49, 101, 0, 255]);
577-
let data_ref = &data;
578-
assert_eq!(data_ref.as_ref(), &[7u8, 35, 49, 101, 0, 255]);
579-
580-
// Implements as ref
581-
582-
// This is a dummy function to mimic the signature of
583-
// https://docs.rs/sha2/0.10.6/sha2/trait.Digest.html#tymethod.digest
584-
fn hash(data: impl AsRef<[u8]>) -> u64 {
585-
let mut hasher = DefaultHasher::new();
586-
data.as_ref().hash(&mut hasher);
587-
hasher.finish()
588-
}
589-
590-
let data = HexBinary(vec![7u8, 35, 49, 101, 0, 255]);
591-
hash(data);
592-
593-
let data = HexBinary(vec![7u8, 35, 49, 101, 0, 255]);
594-
let data_ref = &data;
595-
hash(data_ref);
570+
let want = &[7u8, 35, 49, 101, 0, 255];
571+
let data = HexBinary(want.to_vec());
572+
assert_eq!(want, AsRef::<[u8]>::as_ref(&data));
573+
assert_eq!(want, AsRef::<[u8]>::as_ref(&&data));
596574
}
597575

598576
#[test]
599577
fn hex_binary_implements_hash() {
600-
let a1 = HexBinary::from([0, 187, 61, 11, 250, 0]);
601-
let mut hasher = DefaultHasher::new();
602-
a1.hash(&mut hasher);
603-
let a1_hash = hasher.finish();
604-
605-
let a2 = HexBinary::from([0, 187, 61, 11, 250, 0]);
606-
let mut hasher = DefaultHasher::new();
607-
a2.hash(&mut hasher);
608-
let a2_hash = hasher.finish();
609-
578+
let a = HexBinary::from([0, 187, 61, 11, 250, 0]);
610579
let b = HexBinary::from([16, 21, 33, 0, 255, 9]);
611-
let mut hasher = DefaultHasher::new();
612-
b.hash(&mut hasher);
613-
let b_hash = hasher.finish();
614-
615-
assert_eq!(a1_hash, a2_hash);
616-
assert_ne!(a1_hash, b_hash);
580+
crate::test_utils::check_hash_impl(a, b)
617581
}
618582

619583
/// This requires Hash and Eq to be implemented

packages/std/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,10 @@ pub use crate::imports::{ExternalApi, ExternalQuerier, ExternalStorage};
121121
#[cfg(not(target_arch = "wasm32"))]
122122
pub mod testing;
123123

124+
// Internal testing utilities
125+
#[cfg(test)]
126+
mod test_utils;
127+
124128
// Re-exports
125129

126130
pub use cosmwasm_derive::entry_point;

packages/std/src/test_utils.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//! Module with common routines used internally by the library in unit tests.
2+
3+
use core::hash::{Hash, Hasher};
4+
5+
/// Tests that type `T` implements `Hash` trait correctly.
6+
///
7+
/// `foo` and `bar` must be different objects.
8+
///
9+
/// Some object pairs may produce the same hash causing test failure. In those
10+
/// cases try different objects. The test uses stable hasher so once working
11+
/// pair is identified, the test’s going to continue passing.
12+
pub(crate) fn check_hash_impl<T: Clone + Hash>(foo: T, bar: T) {
13+
let foo_copy = foo.clone();
14+
15+
fn hash<T: Hash>(value: &T) -> u64 {
16+
let mut hasher = crc32fast::Hasher::default();
17+
value.hash(&mut hasher);
18+
hasher.finish()
19+
}
20+
21+
let foo_hash = hash(&foo);
22+
assert_eq!(foo_hash, hash(&foo_copy));
23+
assert_ne!(foo_hash, hash(&bar));
24+
}

0 commit comments

Comments
 (0)