tree_hash/
impls.rs

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)] // Lint does not apply to all uses of this macro.
29            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
136// This implementation covers `Hash256`/`B256` as well.
137impl<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
173/// A helper function providing common functionality for finding the Merkle root of some bytes that
174/// represent a bitfield.
175pub 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        // Note: we use `as_slice` because it does _not_ have the length-delimiting bit set (or
205        // present).
206        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    // Only basic types should be packed.
365    #[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}