1use std::borrow::Cow;
2use std::fmt;
3
4use fake::{Dummy, Fake, Faker};
5use pathfinder_crypto::Felt;
6use rand::Rng;
7use serde::{Deserialize, Serialize};
8use serde_json::value::RawValue;
9use serde_with::serde_as;
10
11use crate::{ByteCodeOffset, EntryPoint};
12
13pub const CLASS_DEFINITION_MAX_ALLOWED_SIZE: u64 = 4 * 1024 * 1024;
14
15#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Dummy)]
16pub struct SerializedSierraDefinition(Vec<u8>);
17
18#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Dummy)]
19pub struct SerializedCasmDefinition(Vec<u8>);
20
21#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Dummy)]
22pub struct SerializedCairoDefinition(Vec<u8>);
23
24#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Dummy)]
27pub struct SerializedOpaqueClassDefinition(Vec<u8>);
28
29#[derive(Clone, Debug)]
32pub enum SerializedClassDefinition {
33 Sierra(SerializedSierraDefinition),
34 Cairo(SerializedCairoDefinition),
35}
36
37#[derive(Debug, Deserialize, Dummy)]
38pub enum ClassDefinition<'a> {
39 Sierra(Sierra<'a>),
40 Cairo(Cairo<'a>),
41}
42
43#[derive(Debug, Clone, Deserialize, Serialize)]
44#[serde(deny_unknown_fields)]
45pub struct Sierra<'a> {
46 pub abi: Cow<'a, str>,
48
49 pub sierra_program: Vec<Felt>,
51
52 pub contract_class_version: Cow<'a, str>,
54
55 pub entry_points_by_type: SierraEntryPoints,
57}
58
59impl<T> Dummy<T> for Sierra<'_> {
60 fn dummy_with_rng<R: Rng + ?Sized>(_: &T, rng: &mut R) -> Self {
61 Self {
62 abi: "[]".into(),
63 sierra_program: Faker.fake_with_rng(rng),
64 contract_class_version: "0.1.0".into(),
65 entry_points_by_type: Faker.fake_with_rng(rng),
66 }
67 }
68}
69
70#[derive(Debug, Deserialize, Serialize)]
71#[serde(deny_unknown_fields)]
72pub struct Cairo<'a> {
73 pub abi: Cow<'a, RawValue>,
75
76 pub program: Cow<'a, RawValue>,
78
79 pub entry_points_by_type: CairoEntryPoints,
81}
82
83impl<T> Dummy<T> for Cairo<'_> {
84 fn dummy_with_rng<R: Rng + ?Sized>(_: &T, rng: &mut R) -> Self {
85 Self {
86 abi: Cow::Owned(
87 RawValue::from_string("[]".into()).unwrap(),
88 ),
89 program: Cow::Owned(
90 RawValue::from_string(
91 r#"
92 {
93 "attributes": [],
94 "builtins": [],
95 "data": [],
96 "debug_info": null,
97 "hints": {},
98 "identifiers": {},
99 "main_scope": "__main__",
100 "prime": "0x800000000000011000000000000000000000000000000000000000000000001",
101 "reference_manager": {}
102 }
103 "#.into()
104 )
105 .unwrap(),
106 ),
107 entry_points_by_type: Faker.fake_with_rng(rng),
108 }
109 }
110}
111
112#[derive(Debug, Clone, Deserialize, Serialize, Dummy)]
113#[serde(deny_unknown_fields)]
114pub struct SierraEntryPoints {
115 #[serde(rename = "EXTERNAL")]
116 pub external: Vec<SelectorAndFunctionIndex>,
117 #[serde(rename = "L1_HANDLER")]
118 pub l1_handler: Vec<SelectorAndFunctionIndex>,
119 #[serde(rename = "CONSTRUCTOR")]
120 pub constructor: Vec<SelectorAndFunctionIndex>,
121}
122
123#[derive(Debug, Deserialize, Serialize, Dummy)]
124#[serde(deny_unknown_fields)]
125pub struct CairoEntryPoints {
126 #[serde(rename = "EXTERNAL")]
127 pub external: Vec<SelectorAndOffset>,
128 #[serde(rename = "L1_HANDLER")]
129 pub l1_handler: Vec<SelectorAndOffset>,
130 #[serde(rename = "CONSTRUCTOR")]
131 pub constructor: Vec<SelectorAndOffset>,
132}
133
134#[derive(Copy, Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq, Hash, Eq)]
135#[serde(deny_unknown_fields)]
136pub enum EntryPointType {
137 #[serde(rename = "EXTERNAL")]
138 External,
139 #[serde(rename = "L1_HANDLER")]
140 L1Handler,
141 #[serde(rename = "CONSTRUCTOR")]
142 Constructor,
143}
144
145impl fmt::Display for EntryPointType {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 use EntryPointType::*;
148 f.pad(match self {
149 External => "EXTERNAL",
150 L1Handler => "L1_HANDLER",
151 Constructor => "CONSTRUCTOR",
152 })
153 }
154}
155
156#[serde_as]
157#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, PartialEq)]
158#[serde(deny_unknown_fields)]
159pub struct SelectorAndOffset {
160 pub selector: EntryPoint,
161 #[serde_as(as = "OffsetSerde")]
162 pub offset: ByteCodeOffset,
163}
164
165#[derive(serde::Deserialize, serde::Serialize)]
166#[serde(untagged)]
167pub enum OffsetSerde {
168 HexStr(Felt),
169 Decimal(u64),
170}
171
172impl serde_with::SerializeAs<ByteCodeOffset> for OffsetSerde {
173 fn serialize_as<S>(source: &ByteCodeOffset, serializer: S) -> Result<S::Ok, S::Error>
174 where
175 S: serde::Serializer,
176 {
177 use serde::Serialize;
178
179 Felt::serialize(&source.0, serializer)
180 }
181}
182
183impl<'de> serde_with::DeserializeAs<'de, ByteCodeOffset> for OffsetSerde {
184 fn deserialize_as<D>(deserializer: D) -> Result<ByteCodeOffset, D::Error>
185 where
186 D: serde::Deserializer<'de>,
187 {
188 use serde::Deserialize;
189
190 let offset = OffsetSerde::deserialize(deserializer)?;
191 let offset = match offset {
192 OffsetSerde::HexStr(felt) => felt,
193 OffsetSerde::Decimal(decimal) => Felt::from_u64(decimal),
194 };
195 Ok(ByteCodeOffset(offset))
196 }
197}
198
199impl<T> Dummy<T> for SelectorAndOffset {
200 fn dummy_with_rng<R: rand::prelude::Rng + ?Sized>(_: &T, rng: &mut R) -> Self {
201 Self {
202 selector: Faker.fake_with_rng(rng),
203 offset: ByteCodeOffset(Felt::from_u64(rng.gen())),
204 }
205 }
206}
207
208#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, Dummy)]
210#[serde(deny_unknown_fields)]
211pub struct SelectorAndFunctionIndex {
212 pub selector: EntryPoint,
213 pub function_idx: u64,
214}
215
216impl SerializedSierraDefinition {
217 pub fn from_bytes(bytes: Vec<u8>) -> Self {
218 Self(bytes)
219 }
220
221 pub fn from_slice(bytes: &[u8]) -> Self {
222 Self(bytes.to_vec())
223 }
224
225 pub fn into_bytes(self) -> Vec<u8> {
226 self.0
227 }
228
229 pub fn as_bytes(&self) -> &[u8] {
230 &self.0
231 }
232}
233
234impl SerializedCasmDefinition {
235 pub fn from_bytes(bytes: Vec<u8>) -> Self {
236 Self(bytes)
237 }
238
239 pub fn from_slice(bytes: &[u8]) -> Self {
240 Self(bytes.to_vec())
241 }
242
243 pub fn into_bytes(self) -> Vec<u8> {
244 self.0
245 }
246
247 pub fn as_bytes(&self) -> &[u8] {
248 &self.0
249 }
250}
251
252impl SerializedCairoDefinition {
253 pub fn from_bytes(bytes: Vec<u8>) -> Self {
254 Self(bytes)
255 }
256
257 pub fn from_slice(bytes: &[u8]) -> Self {
258 Self(bytes.to_vec())
259 }
260
261 pub fn into_bytes(self) -> Vec<u8> {
262 self.0
263 }
264
265 pub fn as_bytes(&self) -> &[u8] {
266 &self.0
267 }
268}
269
270impl SerializedOpaqueClassDefinition {
271 pub fn from_bytes(bytes: Vec<u8>) -> Self {
272 Self(bytes)
273 }
274
275 pub fn from_slice(bytes: &[u8]) -> Self {
276 Self(bytes.to_vec())
277 }
278
279 pub fn into_bytes(self) -> Vec<u8> {
280 self.0
281 }
282
283 pub fn as_bytes(&self) -> &[u8] {
284 &self.0
285 }
286}
287
288impl From<SerializedSierraDefinition> for SerializedOpaqueClassDefinition {
290 fn from(d: SerializedSierraDefinition) -> Self {
291 Self::from_bytes(d.into_bytes())
292 }
293}
294
295impl From<SerializedCairoDefinition> for SerializedOpaqueClassDefinition {
297 fn from(d: SerializedCairoDefinition) -> Self {
298 Self::from_bytes(d.into_bytes())
299 }
300}