1use bobcat_maths::{I, U};
2
3use bobcat_storage::{Keccak256, keccak256_builder};
4
5#[cfg(feature = "alloc")]
6extern crate alloc;
7
8#[cfg(feature = "alloc")]
9use alloc::{string::String, vec::Vec};
10
11#[cfg(not(feature = "std"))]
12mod no_std {
13 #[cfg(feature = "alloc")]
14 use alloc::vec::Vec;
15
16 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
17 pub enum Error {
18 WriteAllEof,
19 ReadExactEof,
20 InvalidData,
21 }
22
23 pub trait Write {
24 fn write(&mut self, buf: &[u8]) -> Result<usize, Error>;
25 fn flush(&mut self) -> Result<(), Error>;
26 fn is_empty(&self) -> bool;
27
28 fn write_all(&mut self, mut buf: &[u8]) -> Result<(), Error> {
29 while !buf.is_empty() {
30 match self.write(buf) {
31 Ok(0) => return Err(Error::WriteAllEof),
32 Ok(n) if n <= buf.len() => buf = &buf[n..],
33 Ok(_) => return Err(Error::InvalidData),
34 Err(error) => return Err(error),
35 }
36 }
37 Ok(())
38 }
39 }
40
41 pub trait Read {
42 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error>;
43
44 fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<(), Error> {
45 while !buf.is_empty() {
46 match self.read(buf) {
47 Ok(0) => break,
48 Ok(n) if n <= buf.len() => buf = &mut buf[n..],
49 Ok(_) => return Err(Error::InvalidData),
50 Err(error) => return Err(error),
51 }
52 }
53 if buf.is_empty() {
54 Ok(())
55 } else {
56 Err(Error::ReadExactEof)
57 }
58 }
59 }
60
61 impl Write for &mut [u8] {
62 fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
63 let len = core::cmp::min(self.len(), buf.len());
64 let target = core::mem::take(self);
65 let (written, remaining) = target.split_at_mut(len);
66 written.copy_from_slice(&buf[..len]);
67 *self = remaining;
68 Ok(len)
69 }
70
71 fn flush(&mut self) -> Result<(), Error> {
72 Ok(())
73 }
74
75 fn is_empty(&self) -> bool {
76 <[u8]>::is_empty(self)
77 }
78 }
79
80 #[cfg(feature = "alloc")]
81 impl Write for Vec<u8> {
82 fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
83 self.extend_from_slice(buf);
84 Ok(buf.len())
85 }
86
87 fn flush(&mut self) -> Result<(), Error> {
88 Ok(())
89 }
90
91 fn is_empty(&self) -> bool {
92 Vec::is_empty(self)
93 }
94 }
95
96 #[cfg(feature = "alloc")]
97 impl Write for &mut Vec<u8> {
98 fn write(&mut self, buf: &[u8]) -> Result<usize, Error> {
99 (**self).write(buf)
100 }
101
102 fn flush(&mut self) -> Result<(), Error> {
103 (**self).flush()
104 }
105
106 fn is_empty(&self) -> bool {
107 Vec::is_empty(self)
108 }
109 }
110
111 impl Read for &[u8] {
112 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
113 let len = core::cmp::min(self.len(), buf.len());
114 buf[..len].copy_from_slice(&self[..len]);
115 *self = &self[len..];
116 Ok(len)
117 }
118 }
119
120 impl Read for &mut [u8] {
121 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error> {
122 let len = core::cmp::min(self.len(), buf.len());
123 let source = core::mem::take(self);
124 let (read, remaining) = source.split_at_mut(len);
125 buf[..len].copy_from_slice(read);
126 *self = remaining;
127 Ok(len)
128 }
129 }
130}
131
132#[cfg(not(feature = "std"))]
133pub use no_std::{Error, Read, Write};
134
135#[cfg(feature = "std")]
136pub use std::io::{Error, Read, Write};
137
138#[doc(hidden)]
139#[derive(Clone)]
140pub struct SelectorHasher(Keccak256);
141
142impl SelectorHasher {
143 pub fn new() -> Self {
144 Self(keccak256_builder())
145 }
146
147 pub fn update(self, bytes: &[u8]) -> Self {
148 Self(self.0.update(bytes))
149 }
150
151 pub fn update_usize(self, mut value: usize) -> Self {
152 let mut digits = [0u8; 20];
153 let mut start = digits.len();
154 loop {
155 start -= 1;
156 digits[start] = b'0' + (value % 10) as u8;
157 value /= 10;
158 if value == 0 {
159 break;
160 }
161 }
162 self.update(&digits[start..])
163 }
164
165 pub fn selector(&self) -> [u8; 4] {
166 let hash = self.0.finalize();
167 [hash[0], hash[1], hash[2], hash[3]]
168 }
169}
170
171impl Default for SelectorHasher {
172 fn default() -> Self {
173 Self::new()
174 }
175}
176
177pub trait EvmCdWriteTarget {
178 type Writer<'a>: Write
179 where
180 Self: 'a;
181
182 fn writer(&mut self) -> Self::Writer<'_>;
183}
184
185impl EvmCdWriteTarget for [u8] {
186 type Writer<'a> = &'a mut [u8];
187
188 fn writer(&mut self) -> Self::Writer<'_> {
189 self
190 }
191}
192
193impl EvmCdWriteTarget for &mut [u8] {
194 type Writer<'a>
195 = &'a mut [u8]
196 where
197 Self: 'a;
198
199 fn writer(&mut self) -> Self::Writer<'_> {
200 self
201 }
202}
203
204impl<const N: usize> EvmCdWriteTarget for [u8; N] {
205 type Writer<'a> = &'a mut [u8];
206
207 fn writer(&mut self) -> Self::Writer<'_> {
208 self.as_mut_slice()
209 }
210}
211
212#[cfg(feature = "alloc")]
213impl EvmCdWriteTarget for Vec<u8> {
214 type Writer<'a> = &'a mut Vec<u8>;
215
216 fn writer(&mut self) -> Self::Writer<'_> {
217 self
218 }
219}
220
221pub trait EvmCdSerialise {
222 fn serialise<W: EvmCdWriteTarget + ?Sized>(&self, writer: &mut W) -> Result<(), Error> {
223 self.serialise_writer(&mut writer.writer())
224 }
225
226 fn serialise_to_array<const N: usize>(&self) -> Result<[u8; N], Error> {
227 let mut output = [0; N];
228 let mut writer = output.as_mut_slice();
229 self.serialise_writer(&mut writer)?;
230 if !writer.is_empty() {
231 return Err(invalid_data());
232 }
233 Ok(output)
234 }
235
236 #[cfg(feature = "alloc")]
237 fn serialise_to_vec(&self) -> Result<Vec<u8>, Error> {
238 let mut output = Vec::new();
239 self.serialise(&mut output)?;
240 Ok(output)
241 }
242
243 #[doc(hidden)]
244 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error>;
245
246 #[doc(hidden)]
247 fn serialise_value<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
248 self.serialise_writer(writer)
249 }
250
251 #[doc(hidden)]
252 fn is_abi_dynamic() -> bool {
253 false
254 }
255
256 #[doc(hidden)]
257 fn abi_head_size() -> usize {
258 32
259 }
260
261 #[doc(hidden)]
262 fn abi_tail_size(&self) -> usize {
263 0
264 }
265
266 #[doc(hidden)]
267 fn serialise_abi_head<W: Write>(
268 &self,
269 _tail_offset: usize,
270 writer: &mut W,
271 ) -> Result<(), Error> {
272 self.serialise_value(writer)
273 }
274
275 #[doc(hidden)]
276 fn serialise_abi_tail<W: Write>(&self, _writer: &mut W) -> Result<(), Error> {
277 Ok(())
278 }
279
280 #[doc(hidden)]
281 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher;
282}
283
284#[doc(hidden)]
285pub enum EvmCdHead<T> {
286 Value(T),
287 Offset(usize),
288}
289
290#[doc(hidden)]
291pub struct EvmCdStaticBufferKind;
292
293#[cfg(feature = "alloc")]
294#[doc(hidden)]
295pub struct EvmCdDynamicBufferKind;
296
297#[doc(hidden)]
298pub trait EvmCdBufferKind {
299 type Buffer<S>: EvmCdDecodeBuffer;
300 type Combined<Rhs: EvmCdBufferKind>: EvmCdBufferKind;
301}
302
303impl EvmCdBufferKind for EvmCdStaticBufferKind {
304 type Buffer<S> = EvmCdBuffer<S>;
305 type Combined<Rhs: EvmCdBufferKind> = Rhs;
306}
307
308#[cfg(feature = "alloc")]
309impl EvmCdBufferKind for EvmCdDynamicBufferKind {
310 type Buffer<S> = EvmCdDynamicBuffer<S>;
311 type Combined<Rhs: EvmCdBufferKind> = EvmCdDynamicBufferKind;
312}
313
314#[doc(hidden)]
315pub trait EvmCdDecodeBuffer: AsRef<[u8]> + AsMut<[u8]> + Sized {
316 type Kind: EvmCdBufferKind;
317
318 fn new(len: usize) -> Result<Self, Error>;
319}
320
321#[doc(hidden)]
322pub struct EvmCdBuffer<S> {
323 storage: core::mem::MaybeUninit<S>,
324}
325
326impl<S> EvmCdDecodeBuffer for EvmCdBuffer<S> {
327 type Kind = EvmCdStaticBufferKind;
328
329 fn new(len: usize) -> Result<Self, Error> {
330 if len > size_of::<S>() {
331 return Err(invalid_data());
332 }
333 let mut storage = core::mem::MaybeUninit::<S>::uninit();
334 unsafe {
337 storage
338 .as_mut_ptr()
339 .cast::<u8>()
340 .write_bytes(0, size_of::<S>())
341 };
342 Ok(Self { storage })
343 }
344}
345
346impl<S> AsRef<[u8]> for EvmCdBuffer<S> {
347 fn as_ref(&self) -> &[u8] {
348 unsafe { core::slice::from_raw_parts(self.storage.as_ptr().cast::<u8>(), size_of::<S>()) }
350 }
351}
352
353impl<S> AsMut<[u8]> for EvmCdBuffer<S> {
354 fn as_mut(&mut self) -> &mut [u8] {
355 unsafe {
357 core::slice::from_raw_parts_mut(self.storage.as_mut_ptr().cast::<u8>(), size_of::<S>())
358 }
359 }
360}
361
362#[cfg(feature = "alloc")]
363#[doc(hidden)]
364pub struct EvmCdDynamicBuffer<S>(Vec<u8>, core::marker::PhantomData<S>);
365
366#[cfg(feature = "alloc")]
367impl<S> EvmCdDecodeBuffer for EvmCdDynamicBuffer<S> {
368 type Kind = EvmCdDynamicBufferKind;
369
370 fn new(len: usize) -> Result<Self, Error> {
371 if len > MAX_ALLOC_DESERIALISE_LEN {
372 return Err(invalid_data());
373 }
374 let mut bytes = Vec::new();
375 bytes.try_reserve_exact(len).map_err(|_| invalid_data())?;
376 bytes.resize(len, 0);
377 Ok(Self(bytes, core::marker::PhantomData))
378 }
379}
380
381#[cfg(feature = "alloc")]
382impl<S> AsRef<[u8]> for EvmCdDynamicBuffer<S> {
383 fn as_ref(&self) -> &[u8] {
384 &self.0
385 }
386}
387
388#[cfg(feature = "alloc")]
389impl<S> AsMut<[u8]> for EvmCdDynamicBuffer<S> {
390 fn as_mut(&mut self) -> &mut [u8] {
391 &mut self.0
392 }
393}
394
395pub trait EvmCdDeserialise: Sized {
396 type Buffer: EvmCdDecodeBuffer;
397
398 fn new_buffer(len: usize) -> Result<Self::Buffer, Error> {
399 Self::Buffer::new(len)
400 }
401
402 fn deserialise<B>(bytes: &B) -> Result<Self, Error>
403 where
404 B: AsRef<[u8]> + ?Sized,
405 {
406 let mut reader = bytes.as_ref();
407 Self::deserialise_reader(&mut reader)
408 }
409
410 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error>;
411
412 #[doc(hidden)]
413 fn deserialise_value<R: Read>(reader: &mut R) -> Result<Self, Error> {
414 Self::deserialise_reader(reader)
415 }
416
417 #[doc(hidden)]
418 fn is_abi_dynamic() -> bool {
419 false
420 }
421
422 #[doc(hidden)]
423 fn abi_head_size() -> usize {
424 32
425 }
426
427 #[doc(hidden)]
428 fn abi_tail_size(&self) -> usize {
429 0
430 }
431
432 #[doc(hidden)]
433 fn deserialise_abi_head<R: Read>(reader: &mut R) -> Result<EvmCdHead<Self>, Error> {
434 Ok(EvmCdHead::Value(Self::deserialise_value(reader)?))
435 }
436
437 #[doc(hidden)]
438 fn deserialise_abi_finish<R: Read>(
439 head: EvmCdHead<Self>,
440 _expected_tail_offset: usize,
441 _reader: &mut R,
442 ) -> Result<Self, Error> {
443 match head {
444 EvmCdHead::Value(value) => Ok(value),
445 EvmCdHead::Offset(_) => Err(invalid_data()),
446 }
447 }
448
449 #[doc(hidden)]
450 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher;
451}
452
453#[cfg(not(feature = "std"))]
454pub fn invalid_data() -> Error {
455 Error::InvalidData
456}
457
458#[cfg(feature = "std")]
459pub fn invalid_data() -> Error {
460 Error::new(std::io::ErrorKind::InvalidData, "invalid EVM calldata")
461}
462
463fn read_usize_word<R: Read>(reader: &mut R) -> Result<usize, Error> {
464 let mut word = [0u8; 32];
465 reader.read_exact(&mut word)?;
466 if word[..32 - size_of::<usize>()]
467 .iter()
468 .any(|byte| *byte != 0)
469 {
470 return Err(invalid_data());
471 }
472 Ok(usize::from_be_bytes(
473 word[32 - size_of::<usize>()..].try_into().unwrap(),
474 ))
475}
476
477fn write_dynamic_tail<W: Write>(bytes: &[u8], writer: &mut W) -> Result<(), Error> {
478 writer.write_all(&U::from_usize(bytes.len()).0)?;
479 writer.write_all(bytes)?;
480 const ZEROES: [u8; 31] = [0; 31];
481 let padding = (32 - bytes.len() % 32) % 32;
482 writer.write_all(&ZEROES[..padding])
483}
484
485fn write_dynamic_bytes<W: Write>(bytes: &[u8], writer: &mut W) -> Result<(), Error> {
486 writer.write_all(&U::from_u32(32).0)?;
487 write_dynamic_tail(bytes, writer)
488}
489
490fn dynamic_tail_size(len: usize) -> usize {
491 32 + len + (32 - len % 32) % 32
492}
493
494fn read_dynamic_tail<const CAP: usize, R: Read>(
495 reader: &mut R,
496) -> Result<([u8; CAP], usize), Error> {
497 let len = read_usize_word(reader)?;
498 if len > CAP {
499 return Err(invalid_data());
500 }
501 let mut bytes = [0u8; CAP];
502 reader.read_exact(&mut bytes[..len])?;
503 let padding = (32 - len % 32) % 32;
504 let mut padding_bytes = [0u8; 31];
505 reader.read_exact(&mut padding_bytes[..padding])?;
506 if padding_bytes[..padding].iter().any(|byte| *byte != 0) {
507 return Err(invalid_data());
508 }
509 Ok((bytes, len))
510}
511
512fn read_dynamic_bytes<const CAP: usize, R: Read>(
513 reader: &mut R,
514) -> Result<([u8; CAP], usize), Error> {
515 if read_usize_word(reader)? != 32 {
516 return Err(invalid_data());
517 }
518 read_dynamic_tail(reader)
519}
520
521macro_rules! fixed_deserialise_buffer {
522 ($storage:ty) => {
523 type Buffer = EvmCdBuffer<$storage>;
524 };
525}
526
527impl EvmCdSerialise for U {
528 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
529 writer.write_all(&self.0)
530 }
531
532 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
533 hasher.update(b"uint256")
534 }
535}
536
537impl EvmCdDeserialise for U {
538 fixed_deserialise_buffer!([u8; 32]);
539
540 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
541 let mut buf = [0u8; 32];
542 reader.read_exact(&mut buf)?;
543 Ok(U(buf))
544 }
545
546 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
547 hasher.update(b"uint256")
548 }
549}
550
551impl EvmCdSerialise for bool {
552 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
553 u8::from(*self).serialise_value(writer)
554 }
555
556 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
557 hasher.update(b"bool")
558 }
559}
560
561impl EvmCdDeserialise for bool {
562 fixed_deserialise_buffer!([u8; 32]);
563
564 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
565 match u8::deserialise_reader(reader)? {
566 0 => Ok(false),
567 1 => Ok(true),
568 _ => Err(invalid_data()),
569 }
570 }
571
572 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
573 hasher.update(b"bool")
574 }
575}
576
577macro_rules! for_ints {
578 ($($ty:ty => $abi:literal),+ $(,)?) => {
579 $(
580 impl EvmCdSerialise for $ty {
581 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
582 writer.write_all(&[0u8; 32 - size_of::<$ty>()])?;
583 writer.write_all(&self.to_be_bytes())
584 }
585
586 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
587 hasher.update($abi)
588 }
589 }
590
591 impl EvmCdDeserialise for $ty {
592 fixed_deserialise_buffer!([u8; 32]);
593
594 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
595 let U(word) = U::deserialise_reader(reader)?;
596 if word[..32 - size_of::<$ty>()].iter().any(|byte| *byte != 0) {
597 return Err(invalid_data());
598 }
599 Ok(<$ty>::from_be_bytes(
600 word[32 - size_of::<$ty>()..].try_into().unwrap(),
601 ))
602 }
603
604 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
605 hasher.update($abi)
606 }
607 }
608 )+
609 };
610}
611
612for_ints! {
613 u8 => b"uint8",
614 u16 => b"uint16",
615 u32 => b"uint32",
616 u64 => b"uint64",
617 u128 => b"uint128",
618}
619
620macro_rules! for_signed_ints {
621 ($($ty:ty => $abi:literal),+ $(,)?) => {
622 $(
623 impl EvmCdSerialise for $ty {
624 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
625 let extension = if self.is_negative() { 0xff } else { 0 };
626 writer.write_all(&[extension; 32 - size_of::<$ty>()])?;
627 writer.write_all(&self.to_be_bytes())
628 }
629
630 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
631 hasher.update($abi)
632 }
633 }
634
635 impl EvmCdDeserialise for $ty {
636 fixed_deserialise_buffer!([u8; 32]);
637
638 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
639 let mut word = [0u8; 32];
640 reader.read_exact(&mut word)?;
641 let value_start = 32 - size_of::<$ty>();
642 let extension = if word[value_start] & 0x80 == 0 { 0 } else { 0xff };
643 if word[..value_start].iter().any(|byte| *byte != extension) {
644 return Err(invalid_data());
645 }
646 Ok(<$ty>::from_be_bytes(word[value_start..].try_into().unwrap()))
647 }
648
649 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
650 hasher.update($abi)
651 }
652 }
653 )+
654 };
655}
656
657for_signed_ints! {
658 i8 => b"int8",
659 i16 => b"int16",
660 i32 => b"int32",
661 i64 => b"int64",
662 i128 => b"int128",
663}
664
665impl EvmCdSerialise for usize {
666 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
667 <u32 as EvmCdSerialise>::serialise_value(
668 &u32::try_from(*self).map_err(|_| invalid_data())?,
669 writer,
670 )
671 }
672
673 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
674 hasher.update(b"uint32")
675 }
676}
677
678impl EvmCdDeserialise for usize {
679 fixed_deserialise_buffer!([u8; 32]);
680
681 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
682 Ok(u32::deserialise_reader(reader)? as usize)
683 }
684
685 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
686 hasher.update(b"uint32")
687 }
688}
689
690macro_rules! evm_cd_uint {
691 ($name:ident, $bits:literal, $bytes:literal) => {
692 #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
693 pub struct $name([u8; $bytes]);
694
695 impl $name {
696 pub const fn new(bytes: [u8; $bytes]) -> Self {
697 Self(bytes)
698 }
699
700 pub const fn into_array(self) -> [u8; $bytes] {
701 self.0
702 }
703
704 pub const fn as_array(&self) -> &[u8; $bytes] {
705 &self.0
706 }
707 }
708
709 impl From<[u8; $bytes]> for $name {
710 fn from(bytes: [u8; $bytes]) -> Self {
711 Self::new(bytes)
712 }
713 }
714
715 impl From<$name> for [u8; $bytes] {
716 fn from(value: $name) -> Self {
717 value.into_array()
718 }
719 }
720
721 impl From<$name> for U {
722 fn from(value: $name) -> Self {
723 let mut word = [0u8; 32];
724 word[32 - $bytes..].copy_from_slice(value.as_array());
725 Self::from(word)
726 }
727 }
728
729 impl From<U> for $name {
730 fn from(value: U) -> Self {
731 let word: [u8; 32] = value.into();
732 Self::new(word[32 - $bytes..].try_into().unwrap())
733 }
734 }
735
736 impl AsRef<[u8; $bytes]> for $name {
737 fn as_ref(&self) -> &[u8; $bytes] {
738 self.as_array()
739 }
740 }
741
742 impl AsRef<[u8]> for $name {
743 fn as_ref(&self) -> &[u8] {
744 self.as_array()
745 }
746 }
747
748 impl EvmCdSerialise for $name {
749 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
750 writer.write_all(&[0; 32 - $bytes])?;
751 writer.write_all(&self.0)
752 }
753
754 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
755 hasher.update(b"uint").update_usize($bits)
756 }
757 }
758
759 impl EvmCdDeserialise for $name {
760 fixed_deserialise_buffer!([u8; 32]);
761
762 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
763 let mut word = [0u8; 32];
764 reader.read_exact(&mut word)?;
765 if word[..32 - $bytes].iter().any(|byte| *byte != 0) {
766 return Err(invalid_data());
767 }
768 Ok(Self(word[32 - $bytes..].try_into().unwrap()))
769 }
770
771 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
772 hasher.update(b"uint").update_usize($bits)
773 }
774 }
775 };
776}
777
778macro_rules! evm_cd_int {
779 ($name:ident, $bits:literal, $bytes:literal) => {
780 #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
781 pub struct $name([u8; $bytes]);
782
783 impl $name {
784 pub const fn new(bytes: [u8; $bytes]) -> Self {
785 Self(bytes)
786 }
787
788 pub const fn into_array(self) -> [u8; $bytes] {
789 self.0
790 }
791
792 pub const fn as_array(&self) -> &[u8; $bytes] {
793 &self.0
794 }
795 }
796
797 impl From<[u8; $bytes]> for $name {
798 fn from(bytes: [u8; $bytes]) -> Self {
799 Self::new(bytes)
800 }
801 }
802
803 impl From<$name> for [u8; $bytes] {
804 fn from(value: $name) -> Self {
805 value.into_array()
806 }
807 }
808
809 impl From<$name> for I {
810 fn from(value: $name) -> Self {
811 let extension = if value.0[0] & 0x80 == 0 { 0 } else { 0xff };
812 let mut word = [extension; 32];
813 word[32 - $bytes..].copy_from_slice(value.as_array());
814 Self::from(word)
815 }
816 }
817
818 impl From<I> for $name {
819 fn from(value: I) -> Self {
820 let word: [u8; 32] = value.into();
821 Self::new(word[32 - $bytes..].try_into().unwrap())
822 }
823 }
824
825 impl AsRef<[u8; $bytes]> for $name {
826 fn as_ref(&self) -> &[u8; $bytes] {
827 self.as_array()
828 }
829 }
830
831 impl AsRef<[u8]> for $name {
832 fn as_ref(&self) -> &[u8] {
833 self.as_array()
834 }
835 }
836
837 impl EvmCdSerialise for $name {
838 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
839 let extension = if self.0[0] & 0x80 == 0 { 0 } else { 0xff };
840 writer.write_all(&[extension; 32 - $bytes])?;
841 writer.write_all(&self.0)
842 }
843
844 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
845 hasher.update(b"int").update_usize($bits)
846 }
847 }
848
849 impl EvmCdDeserialise for $name {
850 fixed_deserialise_buffer!([u8; 32]);
851
852 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
853 let mut word = [0u8; 32];
854 reader.read_exact(&mut word)?;
855 let extension = if word[32 - $bytes] & 0x80 == 0 {
856 0
857 } else {
858 0xff
859 };
860 if word[..32 - $bytes].iter().any(|byte| *byte != extension) {
861 return Err(invalid_data());
862 }
863 Ok(Self(word[32 - $bytes..].try_into().unwrap()))
864 }
865
866 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
867 hasher.update(b"int").update_usize($bits)
868 }
869 }
870 };
871}
872
873macro_rules! evm_cd_integer_range {
874 ($uint_macro:ident, $int_macro:ident) => {
875 $uint_macro!(EvmCdU24, 24, 3);
876 $int_macro!(EvmCdI24, 24, 3);
877 $uint_macro!(EvmCdU40, 40, 5);
878 $int_macro!(EvmCdI40, 40, 5);
879 $uint_macro!(EvmCdU48, 48, 6);
880 $int_macro!(EvmCdI48, 48, 6);
881 $uint_macro!(EvmCdU56, 56, 7);
882 $int_macro!(EvmCdI56, 56, 7);
883 $uint_macro!(EvmCdU72, 72, 9);
884 $int_macro!(EvmCdI72, 72, 9);
885 $uint_macro!(EvmCdU80, 80, 10);
886 $int_macro!(EvmCdI80, 80, 10);
887 $uint_macro!(EvmCdU88, 88, 11);
888 $int_macro!(EvmCdI88, 88, 11);
889 $uint_macro!(EvmCdU96, 96, 12);
890 $int_macro!(EvmCdI96, 96, 12);
891 $uint_macro!(EvmCdU104, 104, 13);
892 $int_macro!(EvmCdI104, 104, 13);
893 $uint_macro!(EvmCdU112, 112, 14);
894 $int_macro!(EvmCdI112, 112, 14);
895 $uint_macro!(EvmCdU120, 120, 15);
896 $int_macro!(EvmCdI120, 120, 15);
897 $uint_macro!(EvmCdU136, 136, 17);
898 $int_macro!(EvmCdI136, 136, 17);
899 $uint_macro!(EvmCdU144, 144, 18);
900 $int_macro!(EvmCdI144, 144, 18);
901 $uint_macro!(EvmCdU152, 152, 19);
902 $int_macro!(EvmCdI152, 152, 19);
903 $uint_macro!(EvmCdU160, 160, 20);
904 $int_macro!(EvmCdI160, 160, 20);
905 $uint_macro!(EvmCdU168, 168, 21);
906 $int_macro!(EvmCdI168, 168, 21);
907 $uint_macro!(EvmCdU176, 176, 22);
908 $int_macro!(EvmCdI176, 176, 22);
909 $uint_macro!(EvmCdU184, 184, 23);
910 $int_macro!(EvmCdI184, 184, 23);
911 $uint_macro!(EvmCdU192, 192, 24);
912 $int_macro!(EvmCdI192, 192, 24);
913 $uint_macro!(EvmCdU200, 200, 25);
914 $int_macro!(EvmCdI200, 200, 25);
915 $uint_macro!(EvmCdU208, 208, 26);
916 $int_macro!(EvmCdI208, 208, 26);
917 $uint_macro!(EvmCdU216, 216, 27);
918 $int_macro!(EvmCdI216, 216, 27);
919 $uint_macro!(EvmCdU224, 224, 28);
920 $int_macro!(EvmCdI224, 224, 28);
921 $uint_macro!(EvmCdU232, 232, 29);
922 $int_macro!(EvmCdI232, 232, 29);
923 $uint_macro!(EvmCdU240, 240, 30);
924 $int_macro!(EvmCdI240, 240, 30);
925 $uint_macro!(EvmCdU248, 248, 31);
926 $int_macro!(EvmCdI248, 248, 31);
927 $uint_macro!(EvmCdU256, 256, 32);
928 $int_macro!(EvmCdI256, 256, 32);
929 };
930}
931
932evm_cd_integer_range!(evm_cd_uint, evm_cd_int);
933
934#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
935pub struct EvmCdAddress([u8; 20]);
936
937impl EvmCdAddress {
938 pub const fn new(bytes: [u8; 20]) -> Self {
939 Self(bytes)
940 }
941
942 pub const fn into_array(self) -> [u8; 20] {
943 self.0
944 }
945
946 pub const fn as_array(&self) -> &[u8; 20] {
947 &self.0
948 }
949}
950
951impl From<[u8; 20]> for EvmCdAddress {
952 fn from(bytes: [u8; 20]) -> Self {
953 Self::new(bytes)
954 }
955}
956
957impl From<EvmCdAddress> for [u8; 20] {
958 fn from(address: EvmCdAddress) -> Self {
959 address.into_array()
960 }
961}
962
963impl AsRef<[u8; 20]> for EvmCdAddress {
964 fn as_ref(&self) -> &[u8; 20] {
965 self.as_array()
966 }
967}
968
969impl AsRef<[u8]> for EvmCdAddress {
970 fn as_ref(&self) -> &[u8] {
971 self.as_array()
972 }
973}
974
975impl EvmCdSerialise for EvmCdAddress {
976 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
977 writer.write_all(&[0; 12])?;
978 writer.write_all(&self.0)
979 }
980
981 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
982 hasher.update(b"address")
983 }
984}
985
986impl EvmCdDeserialise for EvmCdAddress {
987 fixed_deserialise_buffer!([u8; 32]);
988
989 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
990 let mut word = [0u8; 32];
991 reader.read_exact(&mut word)?;
992 if word[..12].iter().any(|byte| *byte != 0) {
993 return Err(invalid_data());
994 }
995 Ok(Self(word[12..].try_into().unwrap()))
996 }
997
998 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
999 hasher.update(b"address")
1000 }
1001}
1002
1003impl<const N: usize> EvmCdSerialise for [u8; N] {
1004 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1005 if N == 0 || N > 32 {
1006 return Err(invalid_data());
1007 }
1008 writer.write_all(self)?;
1009 const ZEROES: [u8; 32] = [0; 32];
1010 writer.write_all(&ZEROES[..32 - N])
1011 }
1012
1013 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1014 hasher.update(b"bytes").update_usize(N)
1015 }
1016}
1017
1018impl<const N: usize> EvmCdDeserialise for [u8; N] {
1019 fixed_deserialise_buffer!([u8; 32]);
1020
1021 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
1022 if N == 0 || N > 32 {
1023 return Err(invalid_data());
1024 }
1025 let mut word = [0u8; 32];
1026 reader.read_exact(&mut word)?;
1027 if word[N..].iter().any(|byte| *byte != 0) {
1028 return Err(invalid_data());
1029 }
1030 Ok(word[..N].try_into().unwrap())
1031 }
1032
1033 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1034 hasher.update(b"bytes").update_usize(N)
1035 }
1036}
1037
1038#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1039pub enum EvmCdArrayError {
1040 InvalidBounds,
1041 TooShort,
1042 TooLong,
1043}
1044
1045pub struct EvmCdArray<T, const MIN: usize, const CAP: usize> {
1046 len: usize,
1047 values: [core::mem::MaybeUninit<T>; CAP],
1048}
1049
1050impl<T, const MIN: usize, const CAP: usize> EvmCdArray<T, MIN, CAP> {
1051 fn empty() -> Self {
1052 Self {
1053 len: 0,
1054 values: [const { core::mem::MaybeUninit::uninit() }; CAP],
1055 }
1056 }
1057
1058 fn validate_len(len: usize) -> Result<(), EvmCdArrayError> {
1059 if MIN > CAP {
1060 return Err(EvmCdArrayError::InvalidBounds);
1061 }
1062 if len < MIN {
1063 return Err(EvmCdArrayError::TooShort);
1064 }
1065 if len > CAP {
1066 return Err(EvmCdArrayError::TooLong);
1067 }
1068 Ok(())
1069 }
1070
1071 fn push(&mut self, value: T) {
1072 debug_assert!(self.len < CAP);
1073 self.values[self.len].write(value);
1074 self.len += 1;
1075 }
1076
1077 pub fn try_from_array(values: [T; CAP], len: usize) -> Result<Self, EvmCdArrayError> {
1078 Self::validate_len(len)?;
1079 let mut out = Self::empty();
1080 for value in values.into_iter().take(len) {
1081 out.push(value);
1082 }
1083 Ok(out)
1084 }
1085
1086 pub fn try_from_slice(values: &[T]) -> Result<Self, EvmCdArrayError>
1087 where
1088 T: Clone,
1089 {
1090 Self::validate_len(values.len())?;
1091 let mut out = Self::empty();
1092 for value in values {
1093 out.push(value.clone());
1094 }
1095 Ok(out)
1096 }
1097
1098 pub const fn len(&self) -> usize {
1099 self.len
1100 }
1101
1102 pub const fn is_empty(&self) -> bool {
1103 self.len == 0
1104 }
1105
1106 pub const fn capacity(&self) -> usize {
1107 CAP
1108 }
1109
1110 pub fn as_slice(&self) -> &[T] {
1111 unsafe { core::slice::from_raw_parts(self.values.as_ptr().cast::<T>(), self.len) }
1114 }
1115}
1116
1117impl<T, const MIN: usize, const CAP: usize> Drop for EvmCdArray<T, MIN, CAP> {
1118 fn drop(&mut self) {
1119 for value in &mut self.values[..self.len] {
1120 unsafe { value.assume_init_drop() };
1122 }
1123 }
1124}
1125
1126impl<T: Clone, const MIN: usize, const CAP: usize> Clone for EvmCdArray<T, MIN, CAP> {
1127 fn clone(&self) -> Self {
1128 Self::try_from_slice(self.as_slice()).expect("an existing EvmCdArray has valid bounds")
1129 }
1130}
1131
1132impl<T: core::fmt::Debug, const MIN: usize, const CAP: usize> core::fmt::Debug
1133 for EvmCdArray<T, MIN, CAP>
1134{
1135 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1136 formatter.debug_list().entries(self.as_slice()).finish()
1137 }
1138}
1139
1140impl<T: PartialEq, const MIN: usize, const CAP: usize> PartialEq for EvmCdArray<T, MIN, CAP> {
1141 fn eq(&self, other: &Self) -> bool {
1142 self.as_slice() == other.as_slice()
1143 }
1144}
1145
1146impl<T: Eq, const MIN: usize, const CAP: usize> Eq for EvmCdArray<T, MIN, CAP> {}
1147
1148impl<T, const MIN: usize, const CAP: usize> AsRef<[T]> for EvmCdArray<T, MIN, CAP> {
1149 fn as_ref(&self) -> &[T] {
1150 self.as_slice()
1151 }
1152}
1153
1154impl<T> EvmCdSerialise for &[T]
1155where
1156 T: EvmCdSerialise,
1157{
1158 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1159 U::from_u32(32).serialise_value(writer)?;
1160 self.serialise_abi_tail(writer)
1161 }
1162
1163 fn is_abi_dynamic() -> bool {
1164 true
1165 }
1166
1167 fn abi_tail_size(&self) -> usize {
1168 self.len()
1169 .saturating_mul(T::abi_head_size())
1170 .saturating_add(32)
1171 .saturating_add(self.iter().fold(0usize, |size, value| {
1172 size.saturating_add(value.abi_tail_size())
1173 }))
1174 }
1175
1176 fn serialise_abi_head<W: Write>(
1177 &self,
1178 tail_offset: usize,
1179 writer: &mut W,
1180 ) -> Result<(), Error> {
1181 U::from_usize(tail_offset).serialise_value(writer)
1182 }
1183
1184 fn serialise_abi_tail<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1185 U::from_usize(self.len()).serialise_value(writer)?;
1186 let mut tail_offset = self
1187 .len()
1188 .checked_mul(T::abi_head_size())
1189 .ok_or_else(invalid_data)?;
1190 for value in *self {
1191 value.serialise_abi_head(tail_offset, writer)?;
1192 tail_offset = tail_offset
1193 .checked_add(value.abi_tail_size())
1194 .ok_or_else(invalid_data)?;
1195 }
1196 for value in *self {
1197 value.serialise_abi_tail(writer)?;
1198 }
1199 Ok(())
1200 }
1201
1202 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1203 T::append_abi_type(hasher).update(b"[]")
1204 }
1205}
1206
1207impl<T, const MIN: usize, const CAP: usize> EvmCdSerialise for EvmCdArray<T, MIN, CAP>
1208where
1209 T: EvmCdSerialise,
1210{
1211 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1212 U::from_u32(32).serialise_value(writer)?;
1213 self.serialise_abi_tail(writer)
1214 }
1215
1216 fn is_abi_dynamic() -> bool {
1217 true
1218 }
1219
1220 fn abi_tail_size(&self) -> usize {
1221 self.len
1222 .saturating_mul(T::abi_head_size())
1223 .saturating_add(32)
1224 .saturating_add(self.as_slice().iter().fold(0usize, |size, value| {
1225 size.saturating_add(value.abi_tail_size())
1226 }))
1227 }
1228
1229 fn serialise_abi_head<W: Write>(
1230 &self,
1231 tail_offset: usize,
1232 writer: &mut W,
1233 ) -> Result<(), Error> {
1234 U::from_usize(tail_offset).serialise_value(writer)
1235 }
1236
1237 fn serialise_abi_tail<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1238 U::from_usize(self.len).serialise_value(writer)?;
1239 let mut tail_offset = self
1240 .len
1241 .checked_mul(T::abi_head_size())
1242 .ok_or_else(invalid_data)?;
1243 for value in self.as_slice() {
1244 value.serialise_abi_head(tail_offset, writer)?;
1245 tail_offset = tail_offset
1246 .checked_add(value.abi_tail_size())
1247 .ok_or_else(invalid_data)?;
1248 }
1249 for value in self.as_slice() {
1250 value.serialise_abi_tail(writer)?;
1251 }
1252 Ok(())
1253 }
1254
1255 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1256 T::append_abi_type(hasher).update(b"[]")
1257 }
1258}
1259
1260impl<T, const MIN: usize, const CAP: usize> EvmCdDeserialise for EvmCdArray<T, MIN, CAP>
1261where
1262 T: EvmCdDeserialise,
1263{
1264 type Buffer = <<T::Buffer as EvmCdDecodeBuffer>::Kind as EvmCdBufferKind>::Buffer<(
1265 [u8; 64],
1266 [T::Buffer; CAP],
1267 )>;
1268
1269 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
1270 if read_usize_word(reader)? != 32 {
1271 return Err(invalid_data());
1272 }
1273 Self::deserialise_tail(reader)
1274 }
1275
1276 fn is_abi_dynamic() -> bool {
1277 true
1278 }
1279
1280 fn abi_tail_size(&self) -> usize {
1281 self.len
1282 .saturating_mul(T::abi_head_size())
1283 .saturating_add(32)
1284 .saturating_add(self.as_slice().iter().fold(0usize, |size, value| {
1285 size.saturating_add(value.abi_tail_size())
1286 }))
1287 }
1288
1289 fn deserialise_abi_head<R: Read>(reader: &mut R) -> Result<EvmCdHead<Self>, Error> {
1290 Ok(EvmCdHead::Offset(read_usize_word(reader)?))
1291 }
1292
1293 fn deserialise_abi_finish<R: Read>(
1294 head: EvmCdHead<Self>,
1295 expected_tail_offset: usize,
1296 reader: &mut R,
1297 ) -> Result<Self, Error> {
1298 match head {
1299 EvmCdHead::Offset(offset) if offset == expected_tail_offset => {
1300 Self::deserialise_tail(reader)
1301 }
1302 _ => Err(invalid_data()),
1303 }
1304 }
1305
1306 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1307 T::append_abi_type(hasher).update(b"[]")
1308 }
1309}
1310
1311impl<T, const MIN: usize, const CAP: usize> EvmCdArray<T, MIN, CAP>
1312where
1313 T: EvmCdDeserialise,
1314{
1315 fn deserialise_tail<R: Read>(reader: &mut R) -> Result<Self, Error> {
1316 let len = read_usize_word(reader)?;
1317 Self::validate_len(len).map_err(|_| invalid_data())?;
1318 let mut out = Self::empty();
1319
1320 if T::is_abi_dynamic() {
1321 let mut offsets = [0usize; CAP];
1322 for offset in &mut offsets[..len] {
1323 match T::deserialise_abi_head(reader)? {
1324 EvmCdHead::Offset(value) => *offset = value,
1325 EvmCdHead::Value(_) => return Err(invalid_data()),
1326 }
1327 }
1328 let mut expected_tail_offset = len
1329 .checked_mul(T::abi_head_size())
1330 .ok_or_else(invalid_data)?;
1331 for offset in offsets[..len].iter().copied() {
1332 let value = T::deserialise_abi_finish(
1333 EvmCdHead::Offset(offset),
1334 expected_tail_offset,
1335 reader,
1336 )?;
1337 expected_tail_offset = expected_tail_offset
1338 .checked_add(value.abi_tail_size())
1339 .ok_or_else(invalid_data)?;
1340 out.push(value);
1341 }
1342 } else {
1343 for _ in 0..len {
1344 let head = T::deserialise_abi_head(reader)?;
1345 out.push(T::deserialise_abi_finish(head, 0, reader)?);
1346 }
1347 }
1348 Ok(out)
1349 }
1350}
1351
1352#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1353pub enum EvmCdBytesError {
1354 TooLong,
1355}
1356
1357#[derive(Clone)]
1358pub struct EvmCdBytes<const CAP: usize> {
1359 len: usize,
1360 bytes: [u8; CAP],
1361}
1362
1363impl<const CAP: usize> EvmCdBytes<CAP> {
1364 pub const fn new() -> Self {
1365 Self {
1366 len: 0,
1367 bytes: [0; CAP],
1368 }
1369 }
1370
1371 pub fn try_from_slice(value: &[u8]) -> Result<Self, EvmCdBytesError> {
1372 if value.len() > CAP {
1373 return Err(EvmCdBytesError::TooLong);
1374 }
1375 let mut bytes = [0; CAP];
1376 bytes[..value.len()].copy_from_slice(value);
1377 Ok(Self {
1378 len: value.len(),
1379 bytes,
1380 })
1381 }
1382
1383 pub fn try_from_serialised<T: EvmCdSerialise + ?Sized>(value: &T) -> Result<Self, Error> {
1384 let mut bytes = Self::new();
1385 value.serialise(&mut bytes)?;
1386 Ok(bytes)
1387 }
1388
1389 pub const fn len(&self) -> usize {
1390 self.len
1391 }
1392
1393 pub const fn is_empty(&self) -> bool {
1394 self.len == 0
1395 }
1396
1397 pub const fn capacity(&self) -> usize {
1398 CAP
1399 }
1400
1401 pub fn as_slice(&self) -> &[u8] {
1402 &self.bytes[..self.len]
1403 }
1404
1405 pub fn clear(&mut self) {
1406 self.len = 0;
1407 }
1408
1409 pub fn extend_from_slice(&mut self, value: &[u8]) -> Result<(), EvmCdBytesError> {
1410 let end = self
1411 .len
1412 .checked_add(value.len())
1413 .filter(|end| *end <= CAP)
1414 .ok_or(EvmCdBytesError::TooLong)?;
1415 self.bytes[self.len..end].copy_from_slice(value);
1416 self.len = end;
1417 Ok(())
1418 }
1419}
1420
1421impl<const CAP: usize> Default for EvmCdBytes<CAP> {
1422 fn default() -> Self {
1423 Self::new()
1424 }
1425}
1426
1427impl<const CAP: usize> From<[u8; CAP]> for EvmCdBytes<CAP> {
1428 fn from(bytes: [u8; CAP]) -> Self {
1429 Self { len: CAP, bytes }
1430 }
1431}
1432
1433impl<const CAP: usize> TryFrom<&[u8]> for EvmCdBytes<CAP> {
1434 type Error = EvmCdBytesError;
1435
1436 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
1437 Self::try_from_slice(value)
1438 }
1439}
1440
1441#[cfg(feature = "alloc")]
1442impl<const CAP: usize> TryFrom<Vec<u8>> for EvmCdBytes<CAP> {
1443 type Error = EvmCdBytesError;
1444
1445 fn try_from(value: Vec<u8>) -> Result<Self, Self::Error> {
1446 Self::try_from_slice(&value)
1447 }
1448}
1449
1450impl<const CAP: usize> AsRef<[u8]> for EvmCdBytes<CAP> {
1451 fn as_ref(&self) -> &[u8] {
1452 self.as_slice()
1453 }
1454}
1455
1456impl<const CAP: usize> core::fmt::Debug for EvmCdBytes<CAP> {
1457 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1458 core::fmt::Debug::fmt(self.as_slice(), formatter)
1459 }
1460}
1461
1462impl<const CAP: usize> PartialEq for EvmCdBytes<CAP> {
1463 fn eq(&self, other: &Self) -> bool {
1464 self.as_slice() == other.as_slice()
1465 }
1466}
1467
1468impl<const CAP: usize> Eq for EvmCdBytes<CAP> {}
1469
1470impl<const CAP: usize> PartialOrd for EvmCdBytes<CAP> {
1471 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1472 Some(self.cmp(other))
1473 }
1474}
1475
1476impl<const CAP: usize> Ord for EvmCdBytes<CAP> {
1477 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1478 self.as_slice().cmp(other.as_slice())
1479 }
1480}
1481
1482impl<const CAP: usize> core::hash::Hash for EvmCdBytes<CAP> {
1483 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
1484 core::hash::Hash::hash(self.as_slice(), state)
1485 }
1486}
1487
1488#[doc(hidden)]
1489pub struct EvmCdBytesWriter<'a, const CAP: usize> {
1490 bytes: &'a mut EvmCdBytes<CAP>,
1491}
1492
1493#[cfg(not(feature = "std"))]
1494impl<const CAP: usize> Write for EvmCdBytesWriter<'_, CAP> {
1495 fn write(&mut self, value: &[u8]) -> Result<usize, Error> {
1496 let written = core::cmp::min(CAP - self.bytes.len, value.len());
1497 let end = self.bytes.len + written;
1498 self.bytes.bytes[self.bytes.len..end].copy_from_slice(&value[..written]);
1499 self.bytes.len = end;
1500 Ok(written)
1501 }
1502
1503 fn flush(&mut self) -> Result<(), Error> {
1504 Ok(())
1505 }
1506
1507 fn is_empty(&self) -> bool {
1508 self.bytes.len == CAP
1509 }
1510}
1511
1512#[cfg(feature = "std")]
1513impl<const CAP: usize> Write for EvmCdBytesWriter<'_, CAP> {
1514 fn write(&mut self, value: &[u8]) -> Result<usize, Error> {
1515 let written = core::cmp::min(CAP - self.bytes.len, value.len());
1516 let end = self.bytes.len + written;
1517 self.bytes.bytes[self.bytes.len..end].copy_from_slice(&value[..written]);
1518 self.bytes.len = end;
1519 Ok(written)
1520 }
1521
1522 fn flush(&mut self) -> Result<(), Error> {
1523 Ok(())
1524 }
1525}
1526
1527impl<const CAP: usize> EvmCdWriteTarget for EvmCdBytes<CAP> {
1528 type Writer<'a> = EvmCdBytesWriter<'a, CAP>;
1529
1530 fn writer(&mut self) -> Self::Writer<'_> {
1531 EvmCdBytesWriter { bytes: self }
1532 }
1533}
1534
1535impl<const CAP: usize> EvmCdSerialise for EvmCdBytes<CAP> {
1536 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1537 write_dynamic_bytes(self.as_slice(), writer)
1538 }
1539
1540 fn is_abi_dynamic() -> bool {
1541 true
1542 }
1543
1544 fn abi_tail_size(&self) -> usize {
1545 dynamic_tail_size(self.len)
1546 }
1547
1548 fn serialise_abi_head<W: Write>(
1549 &self,
1550 tail_offset: usize,
1551 writer: &mut W,
1552 ) -> Result<(), Error> {
1553 U::from_usize(tail_offset).serialise_value(writer)
1554 }
1555
1556 fn serialise_abi_tail<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1557 write_dynamic_tail(self.as_slice(), writer)
1558 }
1559
1560 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1561 hasher.update(b"bytes")
1562 }
1563}
1564
1565impl<const CAP: usize> EvmCdDeserialise for EvmCdBytes<CAP> {
1566 type Buffer = EvmCdBuffer<([u8; 64], [u8; CAP], [u8; 31])>;
1567
1568 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
1569 let (bytes, len) = read_dynamic_bytes::<CAP, _>(reader)?;
1570 Ok(Self { len, bytes })
1571 }
1572
1573 fn is_abi_dynamic() -> bool {
1574 true
1575 }
1576
1577 fn abi_tail_size(&self) -> usize {
1578 dynamic_tail_size(self.len)
1579 }
1580
1581 fn deserialise_abi_head<R: Read>(reader: &mut R) -> Result<EvmCdHead<Self>, Error> {
1582 Ok(EvmCdHead::Offset(read_usize_word(reader)?))
1583 }
1584
1585 fn deserialise_abi_finish<R: Read>(
1586 head: EvmCdHead<Self>,
1587 expected_tail_offset: usize,
1588 reader: &mut R,
1589 ) -> Result<Self, Error> {
1590 match head {
1591 EvmCdHead::Offset(offset) if offset == expected_tail_offset => {
1592 let (bytes, len) = read_dynamic_tail::<CAP, _>(reader)?;
1593 Ok(Self { len, bytes })
1594 }
1595 _ => Err(invalid_data()),
1596 }
1597 }
1598
1599 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1600 hasher.update(b"bytes")
1601 }
1602}
1603
1604#[derive(Debug, Clone, Copy, PartialEq, Eq)]
1605pub enum EvmCdStringError {
1606 InvalidBounds,
1607 TooShort,
1608 TooLong,
1609}
1610
1611#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
1612pub struct EvmCdString<const MIN: usize, const CAP: usize> {
1613 len: usize,
1614 bytes: [u8; CAP],
1615}
1616
1617impl<const MIN: usize, const CAP: usize> EvmCdString<MIN, CAP> {
1618 pub fn try_from_str(value: &str) -> Result<Self, EvmCdStringError> {
1619 if MIN > CAP {
1620 return Err(EvmCdStringError::InvalidBounds);
1621 }
1622 if value.len() < MIN {
1623 return Err(EvmCdStringError::TooShort);
1624 }
1625 if value.len() > CAP {
1626 return Err(EvmCdStringError::TooLong);
1627 }
1628 let mut bytes = [0u8; CAP];
1629 bytes[..value.len()].copy_from_slice(value.as_bytes());
1630 Ok(Self {
1631 len: value.len(),
1632 bytes,
1633 })
1634 }
1635
1636 pub const fn len(&self) -> usize {
1637 self.len
1638 }
1639
1640 pub const fn is_empty(&self) -> bool {
1641 self.len == 0
1642 }
1643
1644 pub const fn capacity(&self) -> usize {
1645 CAP
1646 }
1647
1648 pub fn as_bytes(&self) -> &[u8] {
1649 &self.bytes[..self.len]
1650 }
1651
1652 pub fn as_str(&self) -> &str {
1653 unsafe { core::str::from_utf8_unchecked(self.as_bytes()) }
1656 }
1657}
1658
1659impl<const MIN: usize, const CAP: usize> TryFrom<&str> for EvmCdString<MIN, CAP> {
1660 type Error = EvmCdStringError;
1661
1662 fn try_from(value: &str) -> Result<Self, Self::Error> {
1663 Self::try_from_str(value)
1664 }
1665}
1666
1667impl<const MIN: usize, const CAP: usize> AsRef<str> for EvmCdString<MIN, CAP> {
1668 fn as_ref(&self) -> &str {
1669 self.as_str()
1670 }
1671}
1672
1673impl<const MIN: usize, const CAP: usize> AsRef<[u8]> for EvmCdString<MIN, CAP> {
1674 fn as_ref(&self) -> &[u8] {
1675 self.as_bytes()
1676 }
1677}
1678
1679impl<const MIN: usize, const CAP: usize> core::borrow::Borrow<str> for EvmCdString<MIN, CAP> {
1680 fn borrow(&self) -> &str {
1681 self.as_str()
1682 }
1683}
1684
1685impl<const MIN: usize, const CAP: usize> core::fmt::Display for EvmCdString<MIN, CAP> {
1686 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1687 formatter.write_str(self.as_str())
1688 }
1689}
1690
1691impl<const MIN: usize, const CAP: usize> core::fmt::Debug for EvmCdString<MIN, CAP> {
1692 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1693 core::fmt::Debug::fmt(self.as_str(), formatter)
1694 }
1695}
1696
1697impl<const MIN: usize, const CAP: usize> core::str::FromStr for EvmCdString<MIN, CAP> {
1698 type Err = EvmCdStringError;
1699
1700 fn from_str(value: &str) -> Result<Self, Self::Err> {
1701 Self::try_from_str(value)
1702 }
1703}
1704
1705impl<const MIN: usize, const CAP: usize> EvmCdSerialise for EvmCdString<MIN, CAP> {
1706 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1707 write_dynamic_bytes(self.as_bytes(), writer)
1708 }
1709
1710 fn is_abi_dynamic() -> bool {
1711 true
1712 }
1713
1714 fn abi_tail_size(&self) -> usize {
1715 dynamic_tail_size(self.len)
1716 }
1717
1718 fn serialise_abi_head<W: Write>(
1719 &self,
1720 tail_offset: usize,
1721 writer: &mut W,
1722 ) -> Result<(), Error> {
1723 U::from_usize(tail_offset).serialise_value(writer)
1724 }
1725
1726 fn serialise_abi_tail<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1727 write_dynamic_tail(self.as_bytes(), writer)
1728 }
1729
1730 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1731 hasher.update(b"string")
1732 }
1733}
1734
1735impl<const MIN: usize, const CAP: usize> EvmCdDeserialise for EvmCdString<MIN, CAP> {
1736 type Buffer = EvmCdBuffer<([u8; 64], [u8; CAP], [u8; 31])>;
1737
1738 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
1739 if MIN > CAP {
1740 return Err(invalid_data());
1741 }
1742 let (bytes, len) = read_dynamic_bytes::<CAP, _>(reader)?;
1743 if len < MIN || core::str::from_utf8(&bytes[..len]).is_err() {
1744 return Err(invalid_data());
1745 }
1746 Ok(Self { len, bytes })
1747 }
1748
1749 fn is_abi_dynamic() -> bool {
1750 true
1751 }
1752
1753 fn abi_tail_size(&self) -> usize {
1754 dynamic_tail_size(self.len)
1755 }
1756
1757 fn deserialise_abi_head<R: Read>(reader: &mut R) -> Result<EvmCdHead<Self>, Error> {
1758 Ok(EvmCdHead::Offset(read_usize_word(reader)?))
1759 }
1760
1761 fn deserialise_abi_finish<R: Read>(
1762 head: EvmCdHead<Self>,
1763 expected_tail_offset: usize,
1764 reader: &mut R,
1765 ) -> Result<Self, Error> {
1766 match head {
1767 EvmCdHead::Offset(offset) if offset == expected_tail_offset => {
1768 if MIN > CAP {
1769 return Err(invalid_data());
1770 }
1771 let (bytes, len) = read_dynamic_tail::<CAP, _>(reader)?;
1772 if len < MIN || core::str::from_utf8(&bytes[..len]).is_err() {
1773 return Err(invalid_data());
1774 }
1775 Ok(Self { len, bytes })
1776 }
1777 _ => Err(invalid_data()),
1778 }
1779 }
1780
1781 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1782 hasher.update(b"string")
1783 }
1784}
1785
1786#[cfg(feature = "alloc")]
1787impl<const MIN: usize, const CAP: usize> From<EvmCdString<MIN, CAP>> for String {
1788 fn from(value: EvmCdString<MIN, CAP>) -> Self {
1789 String::from(value.as_str())
1790 }
1791}
1792
1793#[cfg(feature = "alloc")]
1794fn vec_is_bytes<T: 'static>() -> bool {
1795 core::any::TypeId::of::<T>() == core::any::TypeId::of::<u8>()
1796}
1797
1798#[cfg(feature = "alloc")]
1799fn vec_as_bytes<T: 'static>(values: &[T]) -> &[u8] {
1800 debug_assert!(vec_is_bytes::<T>());
1801 unsafe { core::slice::from_raw_parts(values.as_ptr().cast::<u8>(), values.len()) }
1803}
1804
1805#[cfg(feature = "alloc")]
1806impl<T> EvmCdSerialise for Vec<T>
1807where
1808 T: EvmCdSerialise + 'static,
1809{
1810 fn serialise_writer<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1811 U::from_u32(32).serialise_value(writer)?;
1812 self.serialise_abi_tail(writer)
1813 }
1814
1815 fn is_abi_dynamic() -> bool {
1816 true
1817 }
1818
1819 fn abi_tail_size(&self) -> usize {
1820 if vec_is_bytes::<T>() {
1821 dynamic_tail_size(self.len())
1822 } else {
1823 self.len()
1824 .saturating_mul(T::abi_head_size())
1825 .saturating_add(32)
1826 .saturating_add(self.iter().fold(0usize, |size, value| {
1827 size.saturating_add(value.abi_tail_size())
1828 }))
1829 }
1830 }
1831
1832 fn serialise_abi_head<W: Write>(
1833 &self,
1834 tail_offset: usize,
1835 writer: &mut W,
1836 ) -> Result<(), Error> {
1837 U::from_usize(tail_offset).serialise_value(writer)
1838 }
1839
1840 fn serialise_abi_tail<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
1841 if vec_is_bytes::<T>() {
1842 return write_dynamic_tail(vec_as_bytes(self), writer);
1843 }
1844
1845 U::from_usize(self.len()).serialise_value(writer)?;
1846 let mut tail_offset = self
1847 .len()
1848 .checked_mul(T::abi_head_size())
1849 .ok_or_else(invalid_data)?;
1850 for value in self {
1851 value.serialise_abi_head(tail_offset, writer)?;
1852 tail_offset = tail_offset
1853 .checked_add(value.abi_tail_size())
1854 .ok_or_else(invalid_data)?;
1855 }
1856 for value in self {
1857 value.serialise_abi_tail(writer)?;
1858 }
1859 Ok(())
1860 }
1861
1862 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
1863 if vec_is_bytes::<T>() {
1864 hasher.update(b"bytes")
1865 } else {
1866 T::append_abi_type(hasher).update(b"[]")
1867 }
1868 }
1869}
1870
1871#[cfg(feature = "alloc")]
1872const MAX_ALLOC_DESERIALISE_LEN: usize = 16 * 1024 * 1024;
1873
1874#[cfg(feature = "alloc")]
1875fn read_vec_bytes_tail<R: Read>(reader: &mut R) -> Result<Vec<u8>, Error> {
1876 let len = read_usize_word(reader)?;
1877 if len > MAX_ALLOC_DESERIALISE_LEN {
1878 return Err(invalid_data());
1879 }
1880 let mut out = Vec::new();
1881 out.try_reserve_exact(len).map_err(|_| invalid_data())?;
1882 out.resize(len, 0);
1883 reader.read_exact(&mut out)?;
1884 let padding = (32 - len % 32) % 32;
1885 let mut padding_bytes = [0u8; 31];
1886 reader.read_exact(&mut padding_bytes[..padding])?;
1887 if padding_bytes[..padding].iter().any(|byte| *byte != 0) {
1888 return Err(invalid_data());
1889 }
1890 Ok(out)
1891}
1892
1893#[cfg(feature = "alloc")]
1894fn bytes_into_vec<T: 'static>(bytes: Vec<u8>) -> Vec<T> {
1895 debug_assert!(vec_is_bytes::<T>());
1896 let mut bytes = core::mem::ManuallyDrop::new(bytes);
1897 unsafe {
1899 Vec::from_raw_parts(
1900 bytes.as_mut_ptr().cast::<T>(),
1901 bytes.len(),
1902 bytes.capacity(),
1903 )
1904 }
1905}
1906
1907#[cfg(feature = "alloc")]
1908fn validate_vec_array_len<T: EvmCdDeserialise>(len: usize) -> Result<(), Error> {
1909 let head_bytes = len
1910 .checked_mul(T::abi_head_size())
1911 .ok_or_else(invalid_data)?;
1912 let value_bytes = len
1913 .checked_mul(core::mem::size_of::<T>())
1914 .ok_or_else(invalid_data)?;
1915 let offset_bytes = if T::is_abi_dynamic() {
1916 len.checked_mul(core::mem::size_of::<usize>())
1917 .ok_or_else(invalid_data)?
1918 } else {
1919 0
1920 };
1921 if head_bytes > MAX_ALLOC_DESERIALISE_LEN
1922 || value_bytes > MAX_ALLOC_DESERIALISE_LEN
1923 || offset_bytes > MAX_ALLOC_DESERIALISE_LEN
1924 {
1925 return Err(invalid_data());
1926 }
1927 Ok(())
1928}
1929
1930#[cfg(feature = "alloc")]
1931fn read_vec_array_tail<T, R>(reader: &mut R) -> Result<Vec<T>, Error>
1932where
1933 T: EvmCdDeserialise + 'static,
1934 R: Read,
1935{
1936 let len = read_usize_word(reader)?;
1937 validate_vec_array_len::<T>(len)?;
1938
1939 let mut out = Vec::new();
1940 out.try_reserve_exact(len).map_err(|_| invalid_data())?;
1941 if T::is_abi_dynamic() {
1942 let mut offsets = Vec::new();
1943 offsets.try_reserve_exact(len).map_err(|_| invalid_data())?;
1944 for _ in 0..len {
1945 match T::deserialise_abi_head(reader)? {
1946 EvmCdHead::Offset(offset) => offsets.push(offset),
1947 EvmCdHead::Value(_) => return Err(invalid_data()),
1948 }
1949 }
1950 let mut expected_tail_offset = len
1951 .checked_mul(T::abi_head_size())
1952 .ok_or_else(invalid_data)?;
1953 for offset in offsets {
1954 let value =
1955 T::deserialise_abi_finish(EvmCdHead::Offset(offset), expected_tail_offset, reader)?;
1956 expected_tail_offset = expected_tail_offset
1957 .checked_add(value.abi_tail_size())
1958 .ok_or_else(invalid_data)?;
1959 out.push(value);
1960 }
1961 } else {
1962 for _ in 0..len {
1963 let head = T::deserialise_abi_head(reader)?;
1964 out.push(T::deserialise_abi_finish(head, 0, reader)?);
1965 }
1966 }
1967 Ok(out)
1968}
1969
1970#[cfg(feature = "alloc")]
1971fn read_vec_tail<T, R>(reader: &mut R) -> Result<Vec<T>, Error>
1972where
1973 T: EvmCdDeserialise + 'static,
1974 R: Read,
1975{
1976 if vec_is_bytes::<T>() {
1977 read_vec_bytes_tail(reader).map(bytes_into_vec)
1978 } else {
1979 read_vec_array_tail(reader)
1980 }
1981}
1982
1983#[cfg(feature = "alloc")]
1984impl<T> EvmCdDeserialise for Vec<T>
1985where
1986 T: EvmCdDeserialise + 'static,
1987{
1988 type Buffer = EvmCdDynamicBuffer<()>;
1989
1990 fn deserialise_reader<R: Read>(reader: &mut R) -> Result<Self, Error> {
1991 if read_usize_word(reader)? != 32 {
1992 return Err(invalid_data());
1993 }
1994 read_vec_tail(reader)
1995 }
1996
1997 fn is_abi_dynamic() -> bool {
1998 true
1999 }
2000
2001 fn abi_tail_size(&self) -> usize {
2002 if vec_is_bytes::<T>() {
2003 dynamic_tail_size(self.len())
2004 } else {
2005 self.len()
2006 .saturating_mul(T::abi_head_size())
2007 .saturating_add(32)
2008 .saturating_add(self.iter().fold(0usize, |size, value| {
2009 size.saturating_add(value.abi_tail_size())
2010 }))
2011 }
2012 }
2013
2014 fn deserialise_abi_head<R: Read>(reader: &mut R) -> Result<EvmCdHead<Self>, Error> {
2015 Ok(EvmCdHead::Offset(read_usize_word(reader)?))
2016 }
2017
2018 fn deserialise_abi_finish<R: Read>(
2019 head: EvmCdHead<Self>,
2020 expected_tail_offset: usize,
2021 reader: &mut R,
2022 ) -> Result<Self, Error> {
2023 match head {
2024 EvmCdHead::Offset(offset) if offset == expected_tail_offset => read_vec_tail(reader),
2025 _ => Err(invalid_data()),
2026 }
2027 }
2028
2029 fn append_abi_type(hasher: SelectorHasher) -> SelectorHasher {
2030 if vec_is_bytes::<T>() {
2031 hasher.update(b"bytes")
2032 } else {
2033 T::append_abi_type(hasher).update(b"[]")
2034 }
2035 }
2036}
2037
2038#[cfg(all(test, not(feature = "std")))]
2039mod tests {
2040 use super::{EvmCdDeserialise, EvmCdSerialise};
2041
2042 #[derive(
2043 Debug, PartialEq, Eq, bobcat_cd_derive::EvmCdSerialise, bobcat_cd_derive::EvmCdDeserialise,
2044 )]
2045 struct SliceValue {
2046 small: u8,
2047 large: u32,
2048 }
2049
2050 #[test]
2051 fn mutable_slice_is_a_serialisation_writer_and_deserialisation_reader() {
2052 let value = SliceValue {
2053 small: 7,
2054 large: 0x1234_5678,
2055 };
2056 let mut storage = [0u8; 64];
2057
2058 let mut writer = storage.as_mut_slice();
2059 value.serialise(&mut writer).unwrap();
2060 assert!(writer.is_empty());
2061
2062 let mut reader = storage.as_mut_slice();
2063 assert_eq!(SliceValue::deserialise_reader(&mut reader).unwrap(), value);
2064 assert!(reader.is_empty());
2065 }
2066}