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