1use alloc::vec::Vec;
4use core::num::NonZeroU32;
5use digest::Digest;
6use digest::typenum::U32;
7
8use crate::merkle::merkleize;
9use crate::merkle::pack_bytes;
10use crate::union::option_selector_hash;
11use crate::{BYTES_PER_LENGTH_OFFSET, Decode, DecodeError, Encode, HashTreeRoot, read_slice};
12
13macro_rules! impl_uint {
18 ($t:ty, $size:expr) => {
19 impl Encode for $t {
20 fn is_ssz_fixed_len() -> bool {
21 true
22 }
23 fn ssz_fixed_len() -> usize {
24 $size
25 }
26 fn is_basic_type() -> bool {
27 true
28 }
29 fn ssz_bytes_len(&self) -> usize {
30 $size
31 }
32 fn ssz_append(&self, buf: &mut Vec<u8>) {
33 buf.extend_from_slice(&self.to_le_bytes());
34 }
35 }
36
37 impl Decode for $t {
38 fn is_ssz_fixed_len() -> bool {
39 true
40 }
41 fn ssz_fixed_len() -> usize {
42 $size
43 }
44 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
45 if bytes.len() != $size {
46 return Err(DecodeError::UnexpectedEof {
47 expected: $size,
48 actual: bytes.len(),
49 });
50 }
51 let mut arr = [0u8; $size];
52 arr.copy_from_slice(bytes);
53 Ok(<$t>::from_le_bytes(arr))
54 }
55 }
56
57 impl HashTreeRoot for $t {
58 fn hash_tree_root<D: Digest<OutputSize = U32>>(&self) -> [u8; 32] {
59 let mut chunk = [0u8; 32];
60 chunk[..$size].copy_from_slice(&self.to_le_bytes());
61 chunk
62 }
63 }
64 };
65}
66
67impl_uint!(u8, 1);
68impl_uint!(u16, 2);
69impl_uint!(u32, 4);
70impl_uint!(u64, 8);
71impl_uint!(u128, 16);
72
73impl Encode for bool {
78 fn is_ssz_fixed_len() -> bool {
79 true
80 }
81 fn ssz_fixed_len() -> usize {
82 1
83 }
84 fn is_basic_type() -> bool {
85 true
86 }
87 fn ssz_bytes_len(&self) -> usize {
88 1
89 }
90 fn ssz_append(&self, buf: &mut Vec<u8>) {
91 buf.push(if *self { 1 } else { 0 });
92 }
93}
94
95impl Decode for bool {
96 fn is_ssz_fixed_len() -> bool {
97 true
98 }
99 fn ssz_fixed_len() -> usize {
100 1
101 }
102 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
103 if bytes.len() != 1 {
104 return Err(DecodeError::UnexpectedEof {
105 expected: 1,
106 actual: bytes.len(),
107 });
108 }
109 match bytes[0] {
110 0 => Ok(false),
111 1 => Ok(true),
112 v => Err(DecodeError::InvalidBool(v)),
113 }
114 }
115}
116
117impl HashTreeRoot for bool {
118 fn hash_tree_root<D: Digest<OutputSize = U32>>(&self) -> [u8; 32] {
119 let mut chunk = [0u8; 32];
120 chunk[0] = if *self { 1 } else { 0 };
121 chunk
122 }
123}
124
125impl Encode for NonZeroU32 {
130 fn is_ssz_fixed_len() -> bool {
131 true
132 }
133 fn ssz_fixed_len() -> usize {
134 4
135 }
136 fn ssz_bytes_len(&self) -> usize {
137 4
138 }
139 fn ssz_append(&self, buf: &mut Vec<u8>) {
140 buf.extend_from_slice(&self.get().to_le_bytes());
141 }
142}
143
144impl Decode for NonZeroU32 {
145 fn is_ssz_fixed_len() -> bool {
146 true
147 }
148 fn ssz_fixed_len() -> usize {
149 4
150 }
151 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
152 let raw = u32::from_ssz_bytes(bytes)?;
153 NonZeroU32::new(raw).ok_or(DecodeError::ZeroNonZero)
154 }
155}
156
157impl HashTreeRoot for NonZeroU32 {
158 fn hash_tree_root<D: Digest<OutputSize = U32>>(&self) -> [u8; 32] {
159 let mut chunk = [0u8; 32];
160 chunk[..4].copy_from_slice(&self.get().to_le_bytes());
161 chunk
162 }
163}
164
165#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
174pub struct U256(pub [u8; 32]);
175
176impl Encode for U256 {
177 fn is_ssz_fixed_len() -> bool {
178 true
179 }
180 fn ssz_fixed_len() -> usize {
181 32
182 }
183 fn ssz_bytes_len(&self) -> usize {
184 32
185 }
186 fn ssz_append(&self, buf: &mut Vec<u8>) {
187 buf.extend_from_slice(&self.0);
188 }
189}
190
191impl Decode for U256 {
192 fn is_ssz_fixed_len() -> bool {
193 true
194 }
195 fn ssz_fixed_len() -> usize {
196 32
197 }
198 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
199 if bytes.len() != 32 {
200 return Err(DecodeError::UnexpectedEof {
201 expected: 32,
202 actual: bytes.len(),
203 });
204 }
205 let mut arr = [0u8; 32];
206 arr.copy_from_slice(bytes);
207 Ok(U256(arr))
208 }
209}
210
211impl HashTreeRoot for U256 {
212 fn hash_tree_root<D: Digest<OutputSize = U32>>(&self) -> [u8; 32] {
213 self.0
214 }
215}
216
217impl<const N: usize> Encode for [u8; N] {
222 fn is_ssz_fixed_len() -> bool {
223 true
224 }
225 fn ssz_fixed_len() -> usize {
226 N
227 }
228 fn ssz_bytes_len(&self) -> usize {
229 N
230 }
231 fn ssz_append(&self, buf: &mut Vec<u8>) {
232 buf.extend_from_slice(self);
233 }
234}
235
236impl<const N: usize> Decode for [u8; N] {
237 fn is_ssz_fixed_len() -> bool {
238 true
239 }
240 fn ssz_fixed_len() -> usize {
241 N
242 }
243 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
244 if bytes.len() != N {
245 return Err(DecodeError::UnexpectedEof {
246 expected: N,
247 actual: bytes.len(),
248 });
249 }
250 let mut arr = [0u8; N];
251 arr.copy_from_slice(bytes);
252 Ok(arr)
253 }
254}
255
256impl<const N: usize> HashTreeRoot for [u8; N] {
257 fn hash_tree_root<D: Digest<OutputSize = U32>>(&self) -> [u8; 32] {
258 let chunks = pack_bytes(self);
259 let limit = N.div_ceil(32).max(1);
260 merkleize::<D>(&chunks, limit)
261 }
262}
263
264impl<const N: usize> Encode for [u64; N] {
280 fn is_ssz_fixed_len() -> bool {
281 true
282 }
283 fn ssz_fixed_len() -> usize {
284 N * 8
285 }
286 fn ssz_bytes_len(&self) -> usize {
287 N * 8
288 }
289 fn ssz_append(&self, buf: &mut Vec<u8>) {
290 for v in self {
291 buf.extend_from_slice(&v.to_le_bytes());
292 }
293 }
294}
295
296impl<const N: usize> Decode for [u64; N] {
297 fn is_ssz_fixed_len() -> bool {
298 true
299 }
300 fn ssz_fixed_len() -> usize {
301 N * 8
302 }
303 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
304 if bytes.len() != N * 8 {
305 return Err(DecodeError::UnexpectedEof {
306 expected: N * 8,
307 actual: bytes.len(),
308 });
309 }
310 let mut out = [0u64; N];
311 for (i, v) in out.iter_mut().enumerate() {
312 let s = i * 8;
313 let arr: [u8; 8] = bytes[s..s + 8].try_into().expect("len checked");
314 *v = u64::from_le_bytes(arr);
315 }
316 Ok(out)
317 }
318}
319
320impl<const N: usize> HashTreeRoot for [u64; N] {
321 fn hash_tree_root<D: Digest<OutputSize = U32>>(&self) -> [u8; 32] {
322 let mut buf: Vec<u8> = Vec::with_capacity(N * 8);
326 for v in self {
327 buf.extend_from_slice(&v.to_le_bytes());
328 }
329 let chunks = pack_bytes(&buf);
330 let limit = (N * 8).div_ceil(32).max(1);
331 merkleize::<D>(&chunks, limit)
332 }
333}
334
335impl<T: Encode> Encode for Option<T> {
340 fn is_ssz_fixed_len() -> bool {
341 false
342 }
343 fn ssz_fixed_len() -> usize {
344 BYTES_PER_LENGTH_OFFSET
345 }
346 fn ssz_bytes_len(&self) -> usize {
347 match self {
348 None => 1,
349 Some(t) => 1 + t.ssz_bytes_len(),
350 }
351 }
352 fn ssz_append(&self, buf: &mut Vec<u8>) {
353 match self {
354 None => buf.push(0),
355 Some(t) => {
356 buf.push(1);
357 t.ssz_append(buf);
358 }
359 }
360 }
361}
362
363impl<T: Decode> Decode for Option<T> {
364 fn is_ssz_fixed_len() -> bool {
365 false
366 }
367 fn ssz_fixed_len() -> usize {
368 BYTES_PER_LENGTH_OFFSET
369 }
370 fn from_ssz_bytes(bytes: &[u8]) -> Result<Self, DecodeError> {
371 let selector_byte = read_slice(bytes, 0, 1)?[0];
372 match selector_byte {
373 0 => {
374 if bytes.len() != 1 {
375 return Err(DecodeError::TrailingBytes {
376 expected: 1,
377 actual: bytes.len(),
378 });
379 }
380 Ok(None)
381 }
382 1 => {
383 let inner = T::from_ssz_bytes(&bytes[1..])?;
384 Ok(Some(inner))
385 }
386 v => Err(DecodeError::InvalidSelector(v)),
387 }
388 }
389}
390
391impl<T: HashTreeRoot> HashTreeRoot for Option<T> {
392 fn hash_tree_root<D: Digest<OutputSize = U32>>(&self) -> [u8; 32] {
393 match self {
394 None => option_selector_hash::<D>([0u8; 32], 0),
395 Some(t) => option_selector_hash::<D>(t.hash_tree_root::<D>(), 1),
396 }
397 }
398}