1use super::*;
2use alloy_primitives::{Address, FixedBytes, U128, U256};
3use ssz::{Bitfield, Fixed, Variable};
4use std::sync::Arc;
5use typenum::Unsigned;
6
7fn int_to_hash256(int: u64) -> Hash256 {
8 let mut bytes = [0; HASHSIZE];
9 bytes[0..8].copy_from_slice(&int.to_le_bytes());
10 Hash256::from_slice(&bytes)
11}
12
13macro_rules! impl_for_bitsize {
14 ($type: ident, $bit_size: expr) => {
15 impl TreeHash for $type {
16 fn tree_hash_type() -> TreeHashType {
17 TreeHashType::Basic
18 }
19
20 fn tree_hash_packed_encoding(&self) -> PackedEncoding {
21 PackedEncoding::from_slice(&self.to_le_bytes())
22 }
23
24 fn tree_hash_packing_factor() -> usize {
25 HASHSIZE / ($bit_size / 8)
26 }
27
28 #[allow(clippy::cast_lossless)] fn tree_hash_root(&self) -> Hash256 {
30 int_to_hash256(*self as u64)
31 }
32 }
33 };
34}
35
36impl_for_bitsize!(u8, 8);
37impl_for_bitsize!(u16, 16);
38impl_for_bitsize!(u32, 32);
39impl_for_bitsize!(u64, 64);
40impl_for_bitsize!(usize, 64);
41
42impl TreeHash for bool {
43 fn tree_hash_type() -> TreeHashType {
44 TreeHashType::Basic
45 }
46
47 fn tree_hash_packed_encoding(&self) -> PackedEncoding {
48 (*self as u8).tree_hash_packed_encoding()
49 }
50
51 fn tree_hash_packing_factor() -> usize {
52 u8::tree_hash_packing_factor()
53 }
54
55 fn tree_hash_root(&self) -> Hash256 {
56 int_to_hash256(*self as u64)
57 }
58}
59
60impl<const N: usize> TreeHash for [u8; N] {
61 fn tree_hash_type() -> TreeHashType {
62 TreeHashType::Vector
63 }
64
65 fn tree_hash_packed_encoding(&self) -> PackedEncoding {
66 unreachable!("Vector should never be packed.")
67 }
68
69 fn tree_hash_packing_factor() -> usize {
70 unreachable!("Vector should never be packed.")
71 }
72
73 fn tree_hash_root(&self) -> Hash256 {
74 let values_per_chunk = BYTES_PER_CHUNK;
75 let minimum_chunk_count = N.div_ceil(values_per_chunk);
76 merkle_root(self, minimum_chunk_count)
77 }
78}
79
80impl TreeHash for U128 {
81 fn tree_hash_type() -> TreeHashType {
82 TreeHashType::Basic
83 }
84
85 fn tree_hash_packed_encoding(&self) -> PackedEncoding {
86 PackedEncoding::from_slice(&self.to_le_bytes::<{ Self::BYTES }>())
87 }
88
89 fn tree_hash_packing_factor() -> usize {
90 2
91 }
92
93 fn tree_hash_root(&self) -> Hash256 {
94 Hash256::right_padding_from(&self.to_le_bytes::<{ Self::BYTES }>())
95 }
96}
97
98impl TreeHash for U256 {
99 fn tree_hash_type() -> TreeHashType {
100 TreeHashType::Basic
101 }
102
103 fn tree_hash_packed_encoding(&self) -> PackedEncoding {
104 PackedEncoding::from(self.to_le_bytes::<{ Self::BYTES }>())
105 }
106
107 fn tree_hash_packing_factor() -> usize {
108 1
109 }
110
111 fn tree_hash_root(&self) -> Hash256 {
112 Hash256::from(self.to_le_bytes::<{ Self::BYTES }>())
113 }
114}
115
116impl TreeHash for Address {
117 fn tree_hash_type() -> TreeHashType {
118 TreeHashType::Vector
119 }
120
121 fn tree_hash_packed_encoding(&self) -> PackedEncoding {
122 unreachable!("Vector should never be packed.")
123 }
124
125 fn tree_hash_packing_factor() -> usize {
126 unreachable!("Vector should never be packed.")
127 }
128
129 fn tree_hash_root(&self) -> Hash256 {
130 let mut result = [0; 32];
131 result[0..20].copy_from_slice(self.as_slice());
132 Hash256::from_slice(&result)
133 }
134}
135
136impl<const N: usize> TreeHash for FixedBytes<N> {
138 fn tree_hash_type() -> TreeHashType {
139 TreeHashType::Vector
140 }
141
142 fn tree_hash_packed_encoding(&self) -> PackedEncoding {
143 unreachable!("Vector should never be packed.")
144 }
145
146 fn tree_hash_packing_factor() -> usize {
147 unreachable!("Vector should never be packed.")
148 }
149
150 fn tree_hash_root(&self) -> Hash256 {
151 self.0.tree_hash_root()
152 }
153}
154
155impl<T: TreeHash> TreeHash for Arc<T> {
156 fn tree_hash_type() -> TreeHashType {
157 T::tree_hash_type()
158 }
159
160 fn tree_hash_packed_encoding(&self) -> PackedEncoding {
161 self.as_ref().tree_hash_packed_encoding()
162 }
163
164 fn tree_hash_packing_factor() -> usize {
165 T::tree_hash_packing_factor()
166 }
167
168 fn tree_hash_root(&self) -> Hash256 {
169 self.as_ref().tree_hash_root()
170 }
171}
172
173pub fn bitfield_bytes_tree_hash_root<N: Unsigned>(bytes: &[u8]) -> Hash256 {
176 let byte_size = N::to_usize().div_ceil(8);
177 let leaf_count = byte_size.div_ceil(BYTES_PER_CHUNK);
178
179 let mut hasher = MerkleHasher::with_leaves(leaf_count);
180
181 hasher
182 .write(bytes)
183 .expect("bitfield should not exceed tree hash leaf limit");
184
185 hasher
186 .finish()
187 .expect("bitfield tree hash buffer should not exceed leaf limit")
188}
189
190impl<N: Unsigned + Clone> TreeHash for Bitfield<Variable<N>> {
191 fn tree_hash_type() -> TreeHashType {
192 TreeHashType::List
193 }
194
195 fn tree_hash_packed_encoding(&self) -> PackedEncoding {
196 unreachable!("List should never be packed.")
197 }
198
199 fn tree_hash_packing_factor() -> usize {
200 unreachable!("List should never be packed.")
201 }
202
203 fn tree_hash_root(&self) -> Hash256 {
204 let root = bitfield_bytes_tree_hash_root::<N>(self.as_slice());
207 mix_in_length(&root, self.len())
208 }
209}
210
211impl<N: Unsigned + Clone> TreeHash for Bitfield<Fixed<N>> {
212 fn tree_hash_type() -> TreeHashType {
213 TreeHashType::Vector
214 }
215
216 fn tree_hash_packed_encoding(&self) -> PackedEncoding {
217 unreachable!("Vector should never be packed.")
218 }
219
220 fn tree_hash_packing_factor() -> usize {
221 unreachable!("Vector should never be packed.")
222 }
223
224 fn tree_hash_root(&self) -> Hash256 {
225 bitfield_bytes_tree_hash_root::<N>(self.as_slice())
226 }
227}
228
229#[cfg(test)]
230mod test {
231 use super::*;
232 use ssz::{BitList, BitVector};
233 use std::str::FromStr;
234 use typenum::{U32, U8};
235
236 #[test]
237 fn bool() {
238 let mut true_bytes: Vec<u8> = vec![1];
239 true_bytes.append(&mut vec![0; 31]);
240
241 let false_bytes: Vec<u8> = vec![0; 32];
242
243 assert_eq!(true.tree_hash_root().as_slice(), true_bytes.as_slice());
244 assert_eq!(false.tree_hash_root().as_slice(), false_bytes.as_slice());
245 }
246
247 #[test]
248 fn arc() {
249 let one = U128::from(1);
250 let one_arc = Arc::new(one);
251 assert_eq!(one_arc.tree_hash_root(), one.tree_hash_root());
252 }
253
254 #[test]
255 fn int_to_bytes() {
256 assert_eq!(int_to_hash256(0).as_slice(), &[0; 32]);
257 assert_eq!(
258 int_to_hash256(1).as_slice(),
259 &[
260 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
261 0, 0, 0, 0
262 ]
263 );
264 assert_eq!(
265 int_to_hash256(u64::max_value()).as_slice(),
266 &[
267 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
268 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
269 ]
270 );
271 }
272
273 #[test]
274 fn bitvector() {
275 let empty_bitvector = BitVector::<U8>::new();
276 assert_eq!(empty_bitvector.tree_hash_root(), Hash256::ZERO);
277
278 let small_bitvector_bytes = vec![0xff_u8, 0xee, 0xdd, 0xcc];
279 let small_bitvector =
280 BitVector::<U32>::from_bytes(small_bitvector_bytes.clone().into()).unwrap();
281 assert_eq!(
282 small_bitvector.tree_hash_root().as_slice()[..4],
283 small_bitvector_bytes
284 );
285 }
286
287 #[test]
288 fn bitlist() {
289 let empty_bitlist = BitList::<U8>::with_capacity(8).unwrap();
290 assert_eq!(
291 empty_bitlist.tree_hash_root(),
292 Hash256::from_str("0x5ac78d953211aa822c3ae6e9b0058e42394dd32e5992f29f9c12da3681985130")
293 .unwrap()
294 );
295
296 let mut small_bitlist = BitList::<U32>::with_capacity(4).unwrap();
297 small_bitlist.set(1, true).unwrap();
298 assert_eq!(
299 small_bitlist.tree_hash_root(),
300 Hash256::from_str("0x7eb03d394d83a389980b79897207be3a6512d964cb08978bb7f3cfc0db8cfb8a")
301 .unwrap()
302 );
303 }
304
305 #[test]
306 fn fixed_bytes_7() {
307 let data = [
308 [0, 1, 2, 3, 4, 5, 6],
309 [6, 5, 4, 3, 2, 1, 0],
310 [0, 0, 0, 0, 0, 0, 0],
311 [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
312 ];
313 for bytes in data {
314 assert_eq!(bytes.tree_hash_root(), Hash256::right_padding_from(&bytes));
315 }
316 }
317
318 #[test]
319 fn address() {
320 let data = [
321 Address::ZERO,
322 Address::repeat_byte(0xff),
323 Address::right_padding_from(&[0, 1, 2, 3, 4, 5]),
324 Address::left_padding_from(&[10, 9, 8, 7, 6]),
325 ];
326 for address in data {
327 assert_eq!(
328 address.tree_hash_root(),
329 Hash256::right_padding_from(address.as_slice())
330 );
331 }
332 }
333
334 #[test]
335 fn fixed_bytes_32() {
336 let data = [
337 Hash256::ZERO,
338 Hash256::repeat_byte(0xff),
339 Hash256::right_padding_from(&[0, 1, 2, 3, 4, 5]),
340 Hash256::left_padding_from(&[10, 9, 8, 7, 6]),
341 ];
342 for bytes in data {
343 assert_eq!(bytes.tree_hash_root(), bytes);
344 }
345 }
346
347 #[test]
348 fn fixed_bytes_48() {
349 let data = [
350 (
351 FixedBytes::<48>::ZERO,
352 "0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b",
353 ),
354 (
355 FixedBytes::<48>::repeat_byte(0xff),
356 "0x1e3915ef9ca4ed8619d472b72fb1833448756054b4de9acb439da54dff7166aa",
357 ),
358 ];
359 for (bytes, expected) in data {
360 assert_eq!(bytes.tree_hash_root(), Hash256::from_str(expected).unwrap());
361 }
362 }
363
364 #[test]
366 #[should_panic]
367 fn fixed_bytes_no_packed_encoding() {
368 Hash256::ZERO.tree_hash_packed_encoding();
369 }
370
371 #[test]
372 #[should_panic]
373 fn fixed_bytes_no_packing_factor() {
374 Hash256::tree_hash_packing_factor();
375 }
376
377 #[test]
378 #[should_panic]
379 fn address_no_packed_encoding() {
380 Address::ZERO.tree_hash_packed_encoding();
381 }
382
383 #[test]
384 #[should_panic]
385 fn address_no_packing_factor() {
386 Address::tree_hash_packing_factor();
387 }
388}