Skip to content

Commit cc9e03c

Browse files
committed
fix custom hasher to also use a salt
1 parent 00f4c02 commit cc9e03c

File tree

3 files changed

+30
-13
lines changed

3 files changed

+30
-13
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.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ k256 = { version = "0.13.4", features = ["ecdsa"] }
7777
p256 = { version = "0.13.2", features = ["ecdsa"] }
7878
# for keccak256
7979
sha3 = "0.10.8"
80+
rand = { workspace = true }
8081

8182
[dev-dependencies]
8283
rstest = { workspace = true }

src/serde/read_cache_lookup.rs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use bitvec::prelude::*;
22
use bitvec::vec::BitVec;
3+
use rand::Rng;
34
/// When deserializing a clvm object, a stack of deserialized child objects
45
/// is created, which can be used with back-references. A `ReadCacheLookup` keeps
56
/// track of the state of this stack and all child objects under each root
@@ -23,27 +24,43 @@ use std::hash::{BuildHasher, Hasher};
2324
use super::bytes32::{hash_blob, hash_blobs, Bytes32};
2425

2526
#[derive(Default, Clone, Copy)]
26-
pub struct IdentityHash(u64);
27+
pub struct IdentityHash(u64, u64);
28+
29+
impl IdentityHash {
30+
fn new(salt: u64) -> Self {
31+
Self(0, salt)
32+
}
33+
}
2734

2835
impl Hasher for IdentityHash {
2936
fn finish(&self) -> u64 {
3037
self.0
3138
}
3239

3340
fn write(&mut self, bytes: &[u8]) {
34-
self.0 = u64::from_le_bytes(bytes[0..8].try_into().expect("expected 32 byte hashes"));
41+
self.0 =
42+
u64::from_le_bytes(bytes[0..8].try_into().expect("expected 32 byte hashes")) ^ self.1;
3543
}
3644

3745
fn write_u64(&mut self, _i: u64) {
3846
panic!("This hasher only takes bytes");
3947
}
4048
}
4149

42-
impl BuildHasher for IdentityHash {
43-
type Hasher = Self;
50+
pub struct RandomState(u64);
51+
52+
impl RandomState {
53+
fn new() -> Self {
54+
let mut rng = rand::thread_rng();
55+
Self(rng.gen())
56+
}
57+
}
58+
59+
impl BuildHasher for RandomState {
60+
type Hasher = IdentityHash;
4461

4562
fn build_hasher(&self) -> Self::Hasher {
46-
*self
63+
IdentityHash::new(self.0)
4764
}
4865
}
4966

@@ -56,10 +73,10 @@ pub struct ReadCacheLookup {
5673
/// the tree hashes of the contents on the left and right
5774
read_stack: Vec<(Bytes32, Bytes32)>,
5875

59-
count: HashMap<Bytes32, u32, IdentityHash>,
76+
count: HashMap<Bytes32, u32, RandomState>,
6077

6178
/// a mapping of tree hashes to `(parent, is_right)` tuples
62-
parent_lookup: HashMap<Bytes32, Vec<(Bytes32, bool)>, IdentityHash>,
79+
parent_lookup: HashMap<Bytes32, Vec<(Bytes32, bool)>, RandomState>,
6380
}
6481

6582
impl Default for ReadCacheLookup {
@@ -74,9 +91,9 @@ impl ReadCacheLookup {
7491
let read_stack = Vec::with_capacity(1000);
7592
// all keys in count and parent_lookup are tree-hashes. There's no need
7693
// to hash them again for the hash map
77-
let mut count = HashMap::with_hasher(IdentityHash::default());
94+
let mut count = HashMap::with_hasher(RandomState::new());
7895
count.insert(root_hash, 1);
79-
let parent_lookup = HashMap::with_hasher(IdentityHash::default());
96+
let parent_lookup = HashMap::with_hasher(RandomState::new());
8097
Self {
8198
root_hash,
8299
read_stack,
@@ -161,10 +178,8 @@ impl ReadCacheLookup {
161178

162179
// all the values we put in this hash set are themselves sha256 hashes.
163180
// There's no point in hashing the hashes
164-
let mut seen_ids = HashSet::<&Bytes32, IdentityHash>::with_capacity_and_hasher(
165-
1000,
166-
IdentityHash::default(),
167-
);
181+
let mut seen_ids =
182+
HashSet::<&Bytes32, RandomState>::with_capacity_and_hasher(1000, RandomState::new());
168183

169184
let max_bytes_for_path_encoding = serialized_length - 2; // 1 byte for 0xfe, 1 min byte for savings
170185
let max_path_length: usize = (max_bytes_for_path_encoding.saturating_mul(8) - 1)

0 commit comments

Comments
 (0)