pod_types/ledger/
calldata.rs1use bytes::Bytes;
2use serde::{Deserialize, Serialize};
3
4use crate::{Hashable, Merkleizable, cryptography::merkle_tree::MerkleBuilder};
5
6#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, std::hash::Hash)]
7pub struct CallData(
8 #[serde(
9 serialize_with = "serialize_bytes_as_hex",
10 deserialize_with = "deserialize_bytes_as_hex"
11 )]
12 Bytes,
13);
14
15impl CallData {
16 pub fn new(data: Bytes) -> Self {
18 assert!(data.len() >= 4, "CallData must contain at least 4 bytes");
20 CallData(data)
21 }
22
23 pub fn as_slice(&self) -> &[u8] {
25 &self.0[..]
26 }
27
28 pub fn as_bytes(&self) -> &Bytes {
30 &self.0
31 }
32
33 pub fn empty() -> Self {
34 CallData(Bytes::from(vec![]))
36 }
37
38 pub fn to_hex_string(&self) -> String {
40 let mut result = String::with_capacity(self.0.len() * 2);
41 for &byte in self.0.iter() {
42 result.push_str(&format!("{byte:02x}"));
43 }
44 result
45 }
46
47 pub fn get_function_bytes(&self) -> [u8; 4] {
49 [self.0[0], self.0[1], self.0[2], self.0[3]]
50 }
51
52 pub fn get_body(&self) -> &[u8] {
54 &self.0[4..]
55 }
56}
57
58impl Merkleizable for CallData {
59 fn append_leaves(&self, builder: &mut MerkleBuilder) {
60 builder.add_field("calldata", self.0.hash_custom());
61 }
62}
63
64fn serialize_bytes_as_hex<S>(data: &Bytes, serializer: S) -> Result<S::Ok, S::Error>
65where
66 S: serde::Serializer,
67{
68 if serializer.is_human_readable() {
70 serializer.serialize_str(&hex::encode(data))
71 } else {
72 serializer.serialize_bytes(data)
73 }
74}
75
76fn deserialize_bytes_as_hex<'de, D>(deserializer: D) -> Result<Bytes, D::Error>
78where
79 D: serde::Deserializer<'de>,
80{
81 if deserializer.is_human_readable() {
83 let s = String::deserialize(deserializer)?;
84 Ok(Bytes::from(
85 hex::decode(s).map_err(serde::de::Error::custom)?,
86 ))
87 } else {
88 Ok(Bytes::deserialize(deserializer)?)
89 }
90}