cairo_lang_sierra/extensions/modules/starknet/
syscalls.rs1use itertools::chain;
2
3use super::interoperability::ClassHashType;
4use super::u64_span_ty;
5use crate::extensions::array::ArrayType;
6use crate::extensions::boxing::box_ty;
7use crate::extensions::felt252::Felt252Type;
8use crate::extensions::gas::GasBuiltinType;
9use crate::extensions::int::unsigned::Uint32Type;
10use crate::extensions::lib_func::{
11 BranchSignature, DeferredOutputKind, LibfuncSignature, OutputVarInfo, ParamSignature,
12 SierraApChange, SignatureSpecializationContext,
13};
14use crate::extensions::modules::get_u256_type;
15use crate::extensions::starknet::ContractAddressType;
16use crate::extensions::utils::fixed_size_array_ty;
17use crate::extensions::{
18 NamedType, NoGenericArgsGenericLibfunc, NoGenericArgsGenericType, OutputVarReferenceInfo,
19 SpecializationError,
20};
21use crate::ids::{ConcreteTypeId, GenericTypeId};
22
23#[derive(Default)]
26pub struct SystemType {}
27impl NoGenericArgsGenericType for SystemType {
28 const ID: GenericTypeId = GenericTypeId::new_inline("System");
29 const STORABLE: bool = true;
30 const DUPLICATABLE: bool = false;
31 const DROPPABLE: bool = false;
32 const ZERO_SIZED: bool = false;
33}
34
35pub trait SyscallGenericLibfunc: Default {
37 const STR_ID: &'static str;
39 fn input_tys(
41 context: &dyn SignatureSpecializationContext,
42 ) -> Result<Vec<ConcreteTypeId>, SpecializationError>;
43 fn success_output_tys(
45 context: &dyn SignatureSpecializationContext,
46 ) -> Result<Vec<ConcreteTypeId>, SpecializationError>;
47}
48
49impl<T: SyscallGenericLibfunc> NoGenericArgsGenericLibfunc for T {
50 const STR_ID: &'static str = T::STR_ID;
51
52 fn specialize_signature(
53 &self,
54 context: &dyn SignatureSpecializationContext,
55 ) -> Result<LibfuncSignature, SpecializationError> {
56 let gas_builtin_ty = context.get_concrete_type(GasBuiltinType::id(), &[])?;
57 let system_ty = context.get_concrete_type(SystemType::id(), &[])?;
58 let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?;
59 let felt252_array_ty = context.get_wrapped_concrete_type(ArrayType::id(), felt252_ty)?;
60
61 let gb_output_info = OutputVarInfo {
62 ty: gas_builtin_ty.clone(),
63 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
64 };
65 let system_output_info = OutputVarInfo::new_builtin(system_ty.clone(), 1);
66 Ok(LibfuncSignature {
67 param_signatures: chain!(
68 [
69 ParamSignature::new(gas_builtin_ty),
71 ParamSignature::new(system_ty).with_allow_add_const(),
73 ],
74 T::input_tys(context)?.into_iter().map(ParamSignature::new)
75 )
76 .collect(),
77 branch_signatures: vec![
78 BranchSignature {
80 vars: chain!(
81 [
82 gb_output_info.clone(),
84 system_output_info.clone()
86 ],
87 T::success_output_tys(context)?.into_iter().map(|ty| OutputVarInfo {
88 ty,
89 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
90 })
91 )
92 .collect(),
93 ap_change: SierraApChange::Known { new_vars_only: false },
94 },
95 BranchSignature {
97 vars: vec![
98 gb_output_info,
100 system_output_info,
102 OutputVarInfo {
104 ty: felt252_array_ty,
105 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
106 },
107 ],
108 ap_change: SierraApChange::Known { new_vars_only: false },
109 },
110 ],
111 fallthrough: Some(0),
112 })
113 }
114}
115
116#[derive(Default)]
118pub struct ReplaceClassLibfunc {}
119impl SyscallGenericLibfunc for ReplaceClassLibfunc {
120 const STR_ID: &'static str = "replace_class_syscall";
121
122 fn input_tys(
123 context: &dyn SignatureSpecializationContext,
124 ) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
125 let class_hash_ty = context.get_concrete_type(ClassHashType::id(), &[])?;
126 Ok(vec![
127 class_hash_ty,
129 ])
130 }
131
132 fn success_output_tys(
133 _context: &dyn SignatureSpecializationContext,
134 ) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
135 Ok(vec![])
136 }
137}
138
139#[derive(Default)]
143pub struct KeccakLibfunc {}
144impl SyscallGenericLibfunc for KeccakLibfunc {
145 const STR_ID: &'static str = "keccak_syscall";
146
147 fn input_tys(
148 context: &dyn SignatureSpecializationContext,
149 ) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
150 Ok(vec![
151 u64_span_ty(context)?,
153 ])
154 }
155
156 fn success_output_tys(
157 context: &dyn SignatureSpecializationContext,
158 ) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
159 Ok(vec![get_u256_type(context)?])
160 }
161}
162
163#[derive(Default)]
165pub struct Sha256StateHandleType {}
166
167impl NoGenericArgsGenericType for Sha256StateHandleType {
168 const ID: GenericTypeId = GenericTypeId::new_inline("Sha256StateHandle");
169 const STORABLE: bool = true;
170 const DUPLICATABLE: bool = true;
171 const DROPPABLE: bool = true;
172 const ZERO_SIZED: bool = false;
173}
174
175#[derive(Default)]
179pub struct Sha256ProcessBlockLibfunc {}
180impl SyscallGenericLibfunc for Sha256ProcessBlockLibfunc {
181 const STR_ID: &'static str = "sha256_process_block_syscall";
182
183 fn input_tys(
184 context: &dyn SignatureSpecializationContext,
185 ) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
186 Ok(vec![
187 context.get_concrete_type(Sha256StateHandleType::id(), &[])?,
189 boxed_u32_fixed_array_ty(context, 16)?,
191 ])
192 }
193
194 fn success_output_tys(
195 context: &dyn SignatureSpecializationContext,
196 ) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
197 Ok(vec![context.get_concrete_type(Sha256StateHandleType::id(), &[])?])
198 }
199}
200
201#[derive(Default)]
203pub struct Sha256StateHandleInitLibfunc {}
204impl NoGenericArgsGenericLibfunc for Sha256StateHandleInitLibfunc {
205 const STR_ID: &'static str = "sha256_state_handle_init";
206
207 fn specialize_signature(
208 &self,
209 context: &dyn SignatureSpecializationContext,
210 ) -> Result<LibfuncSignature, SpecializationError> {
211 Ok(LibfuncSignature::new_non_branch_ex(
212 vec![
213 ParamSignature::new(sha256_state_handle_unwrapped_type(context)?).with_allow_all(),
214 ],
215 vec![OutputVarInfo {
216 ty: context.get_concrete_type(Sha256StateHandleType::id(), &[])?,
217 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
218 }],
219 SierraApChange::Known { new_vars_only: false },
220 ))
221 }
222}
223
224#[derive(Default)]
226pub struct Sha256StateHandleDigestLibfunc {}
227impl NoGenericArgsGenericLibfunc for Sha256StateHandleDigestLibfunc {
228 const STR_ID: &'static str = "sha256_state_handle_digest";
229
230 fn specialize_signature(
231 &self,
232 context: &dyn SignatureSpecializationContext,
233 ) -> Result<LibfuncSignature, SpecializationError> {
234 Ok(LibfuncSignature::new_non_branch_ex(
235 vec![
236 ParamSignature::new(context.get_concrete_type(Sha256StateHandleType::id(), &[])?)
237 .with_allow_all(),
238 ],
239 vec![OutputVarInfo {
240 ty: sha256_state_handle_unwrapped_type(context)?,
241 ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
242 }],
243 SierraApChange::Known { new_vars_only: false },
244 ))
245 }
246}
247
248pub fn sha256_state_handle_unwrapped_type(
250 context: &dyn SignatureSpecializationContext,
251) -> Result<ConcreteTypeId, SpecializationError> {
252 boxed_u32_fixed_array_ty(context, 8)
253}
254
255fn boxed_u32_fixed_array_ty(
257 context: &dyn SignatureSpecializationContext,
258 size: i16,
259) -> Result<ConcreteTypeId, SpecializationError> {
260 let ty = context.get_concrete_type(Uint32Type::id(), &[])?;
261 box_ty(context, fixed_size_array_ty(context, ty, size)?)
262}
263
264#[derive(Default)]
266pub struct GetClassHashAtLibfunc {}
267impl SyscallGenericLibfunc for GetClassHashAtLibfunc {
268 const STR_ID: &'static str = "get_class_hash_at_syscall";
269
270 fn input_tys(
271 context: &dyn SignatureSpecializationContext,
272 ) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
273 Ok(vec![context.get_concrete_type(ContractAddressType::id(), &[])?])
274 }
275
276 fn success_output_tys(
277 context: &dyn SignatureSpecializationContext,
278 ) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
279 Ok(vec![context.get_concrete_type(ClassHashType::id(), &[])?])
280 }
281}