cairo_lang_sierra/extensions/modules/starknet/
getter.rs

1use std::marker::PhantomData;
2
3use super::interoperability::ContractAddressType;
4use super::syscalls::SyscallGenericLibfunc;
5use super::{felt252_span_ty, span_ty};
6use crate::extensions::boxing::box_ty;
7use crate::extensions::felt252::Felt252Type;
8use crate::extensions::int::unsigned::{Uint32Type, Uint64Type};
9use crate::extensions::int::unsigned128::Uint128Type;
10use crate::extensions::lib_func::SignatureSpecializationContext;
11use crate::extensions::structure::StructType;
12use crate::extensions::{NamedType, NoGenericArgsGenericType, SpecializationError};
13use crate::ids::{ConcreteTypeId, UserTypeId};
14use crate::program::GenericArg;
15
16/// Trait for implementing getters.
17pub trait GetterTraits: Default {
18    /// The generic libfunc id for the getter libfunc.
19    const STR_ID: &'static str;
20    /// The simple sierra generic type returned by the getter.
21    type InfoType: NoGenericArgsGenericType;
22}
23
24/// Same as GetterTraits, but with a function to return the concrete TypeId.
25pub trait GetterTraitsEx: Default {
26    /// The generic libfunc id for the getter libfunc.
27    const STR_ID: &'static str;
28    /// The simple sierra generic type returned by the getter.
29    fn info_type_id(
30        context: &dyn SignatureSpecializationContext,
31    ) -> Result<ConcreteTypeId, SpecializationError>;
32}
33
34impl<TGetterTraits: GetterTraits> GetterTraitsEx for TGetterTraits {
35    const STR_ID: &'static str = TGetterTraits::STR_ID;
36    fn info_type_id(
37        context: &dyn SignatureSpecializationContext,
38    ) -> Result<ConcreteTypeId, SpecializationError> {
39        context.get_concrete_type(TGetterTraits::InfoType::id(), &[])
40    }
41}
42
43/// Libfunc for a getter system call.
44#[derive(Default)]
45pub struct GetterLibfunc<TGetterTraitsEx: GetterTraitsEx> {
46    _phantom: PhantomData<TGetterTraitsEx>,
47}
48impl<TGetterTraitsEx: GetterTraitsEx> SyscallGenericLibfunc for GetterLibfunc<TGetterTraitsEx> {
49    const STR_ID: &'static str = TGetterTraitsEx::STR_ID;
50
51    fn input_tys(
52        _context: &dyn SignatureSpecializationContext,
53    ) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
54        Ok(vec![])
55    }
56
57    fn success_output_tys(
58        context: &dyn SignatureSpecializationContext,
59    ) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
60        Ok(vec![TGetterTraitsEx::info_type_id(context)?])
61    }
62}
63
64/// Helper for ExecutionInfo type.
65fn get_execution_info_type(
66    context: &dyn SignatureSpecializationContext,
67) -> Result<ConcreteTypeId, SpecializationError> {
68    let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?;
69    let contract_address_ty = context.get_concrete_type(ContractAddressType::id(), &[])?;
70    context.get_concrete_type(StructType::id(), &[
71        GenericArg::UserType(UserTypeId::from_string("core::starknet::info::ExecutionInfo")),
72        // block_info
73        GenericArg::Type(box_ty(context, get_block_info_type(context)?)?),
74        // tx_info
75        GenericArg::Type(box_ty(context, get_tx_info_type(context)?)?),
76        // caller_address
77        GenericArg::Type(contract_address_ty.clone()),
78        // contract_address
79        GenericArg::Type(contract_address_ty),
80        // entry_point_selector
81        GenericArg::Type(felt252_ty),
82    ])
83}
84
85/// Helper for v2::ExecutionInfo type.
86fn get_execution_info_v2_type(
87    context: &dyn SignatureSpecializationContext,
88) -> Result<ConcreteTypeId, SpecializationError> {
89    let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?;
90    let contract_address_ty = context.get_concrete_type(ContractAddressType::id(), &[])?;
91    context.get_concrete_type(StructType::id(), &[
92        GenericArg::UserType(UserTypeId::from_string("core::starknet::info::v2::ExecutionInfo")),
93        // block_info
94        GenericArg::Type(box_ty(context, get_block_info_type(context)?)?),
95        // tx_info
96        GenericArg::Type(box_ty(context, get_tx_info_v2_type(context)?)?),
97        // caller_address
98        GenericArg::Type(contract_address_ty.clone()),
99        // contract_address
100        GenericArg::Type(contract_address_ty),
101        // entry_point_selector
102        GenericArg::Type(felt252_ty),
103    ])
104}
105
106/// Helper for BlockInfo type.
107fn get_block_info_type(
108    context: &dyn SignatureSpecializationContext,
109) -> Result<ConcreteTypeId, SpecializationError> {
110    let contract_address_ty = context.get_concrete_type(ContractAddressType::id(), &[])?;
111    let u64_ty = context.get_concrete_type(Uint64Type::id(), &[])?;
112    context.get_concrete_type(StructType::id(), &[
113        GenericArg::UserType(UserTypeId::from_string("core::starknet::info::BlockInfo")),
114        // block_number
115        GenericArg::Type(u64_ty.clone()),
116        // block_timestamp
117        GenericArg::Type(u64_ty),
118        // sequencer_address
119        GenericArg::Type(contract_address_ty),
120    ])
121}
122
123/// Helper for TxInfo type.
124fn get_tx_info_type(
125    context: &dyn SignatureSpecializationContext,
126) -> Result<ConcreteTypeId, SpecializationError> {
127    let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?;
128    let contract_address_ty = context.get_concrete_type(ContractAddressType::id(), &[])?;
129    let u128_ty = context.get_concrete_type(Uint128Type::id(), &[])?;
130    context.get_concrete_type(StructType::id(), &[
131        GenericArg::UserType(UserTypeId::from_string("core::starknet::info::TxInfo")),
132        // version
133        GenericArg::Type(felt252_ty.clone()),
134        // account_contract_address
135        GenericArg::Type(contract_address_ty),
136        // max_fee
137        GenericArg::Type(u128_ty),
138        // signature
139        GenericArg::Type(felt252_span_ty(context)?),
140        // transaction_hash
141        GenericArg::Type(felt252_ty.clone()),
142        // chain_id
143        GenericArg::Type(felt252_ty.clone()),
144        // nonce
145        GenericArg::Type(felt252_ty),
146    ])
147}
148
149/// Cairo level user type name for `ResourceBounds`.
150const RESOURCE_BOUNDS_USER_TYPE_ID: &str = "core::starknet::info::v2::ResourceBounds";
151
152/// User type for `Span<ResourceBounds>`.
153fn resource_bounds_span_ty(
154    context: &dyn SignatureSpecializationContext,
155) -> Result<ConcreteTypeId, SpecializationError> {
156    span_ty(context, get_resource_bounds_type(context)?, RESOURCE_BOUNDS_USER_TYPE_ID)
157}
158
159/// Helper for ResourceBounds type.
160fn get_resource_bounds_type(
161    context: &dyn SignatureSpecializationContext,
162) -> Result<ConcreteTypeId, SpecializationError> {
163    let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?;
164    let u64_ty = context.get_concrete_type(Uint64Type::id(), &[])?;
165    let u128_ty = context.get_concrete_type(Uint128Type::id(), &[])?;
166    context.get_concrete_type(StructType::id(), &[
167        GenericArg::UserType(UserTypeId::from_string(RESOURCE_BOUNDS_USER_TYPE_ID)),
168        // resource
169        GenericArg::Type(felt252_ty),
170        // max_amount
171        GenericArg::Type(u64_ty),
172        // max_price_per_unit
173        GenericArg::Type(u128_ty),
174    ])
175}
176
177/// Helper for v2::TxInfo type.
178fn get_tx_info_v2_type(
179    context: &dyn SignatureSpecializationContext,
180) -> Result<ConcreteTypeId, SpecializationError> {
181    let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?;
182    let felt252_span_ty = felt252_span_ty(context)?;
183    let contract_address_ty = context.get_concrete_type(ContractAddressType::id(), &[])?;
184    let u32_ty = context.get_concrete_type(Uint32Type::id(), &[])?;
185    let u128_ty = context.get_concrete_type(Uint128Type::id(), &[])?;
186    context.get_concrete_type(StructType::id(), &[
187        GenericArg::UserType(UserTypeId::from_string("core::starknet::info::v2::TxInfo")),
188        // version
189        GenericArg::Type(felt252_ty.clone()),
190        // account_contract_address
191        GenericArg::Type(contract_address_ty),
192        // max_fee
193        GenericArg::Type(u128_ty.clone()),
194        // signature
195        GenericArg::Type(felt252_span_ty.clone()),
196        // transaction_hash
197        GenericArg::Type(felt252_ty.clone()),
198        // chain_id
199        GenericArg::Type(felt252_ty.clone()),
200        // nonce
201        GenericArg::Type(felt252_ty),
202        // resource_bounds
203        GenericArg::Type(resource_bounds_span_ty(context)?),
204        // tip
205        GenericArg::Type(u128_ty),
206        // paymaster_data
207        GenericArg::Type(felt252_span_ty.clone()),
208        // nonce_data_availability_mode
209        GenericArg::Type(u32_ty.clone()),
210        // fee_data_availability_mode
211        GenericArg::Type(u32_ty),
212        // account_deployment_data
213        GenericArg::Type(felt252_span_ty),
214    ])
215}
216
217#[derive(Default)]
218pub struct GetExecutionInfoTrait {}
219impl GetterTraitsEx for GetExecutionInfoTrait {
220    const STR_ID: &'static str = "get_execution_info_syscall";
221
222    fn info_type_id(
223        context: &dyn SignatureSpecializationContext,
224    ) -> Result<ConcreteTypeId, SpecializationError> {
225        box_ty(context, get_execution_info_type(context)?)
226    }
227}
228
229#[derive(Default)]
230pub struct GetExecutionInfoV2Trait {}
231impl GetterTraitsEx for GetExecutionInfoV2Trait {
232    const STR_ID: &'static str = "get_execution_info_v2_syscall";
233
234    fn info_type_id(
235        context: &dyn SignatureSpecializationContext,
236    ) -> Result<ConcreteTypeId, SpecializationError> {
237        box_ty(context, get_execution_info_v2_type(context)?)
238    }
239}