cairo_lang_sierra/extensions/modules/starknet/
syscalls.rsuse itertools::chain;
use super::interoperability::ClassHashType;
use super::u64_span_ty;
use crate::extensions::array::ArrayType;
use crate::extensions::boxing::box_ty;
use crate::extensions::felt252::Felt252Type;
use crate::extensions::gas::GasBuiltinType;
use crate::extensions::int::unsigned::Uint32Type;
use crate::extensions::lib_func::{
BranchSignature, DeferredOutputKind, LibfuncSignature, OutputVarInfo, ParamSignature,
SierraApChange, SignatureSpecializationContext,
};
use crate::extensions::modules::get_u256_type;
use crate::extensions::starknet::ContractAddressType;
use crate::extensions::utils::fixed_size_array_ty;
use crate::extensions::{
NamedType, NoGenericArgsGenericLibfunc, NoGenericArgsGenericType, OutputVarReferenceInfo,
SpecializationError,
};
use crate::ids::{ConcreteTypeId, GenericTypeId};
#[derive(Default)]
pub struct SystemType {}
impl NoGenericArgsGenericType for SystemType {
const ID: GenericTypeId = GenericTypeId::new_inline("System");
const STORABLE: bool = true;
const DUPLICATABLE: bool = false;
const DROPPABLE: bool = false;
const ZERO_SIZED: bool = false;
}
pub trait SyscallGenericLibfunc: Default {
const STR_ID: &'static str;
fn input_tys(
context: &dyn SignatureSpecializationContext,
) -> Result<Vec<ConcreteTypeId>, SpecializationError>;
fn success_output_tys(
context: &dyn SignatureSpecializationContext,
) -> Result<Vec<ConcreteTypeId>, SpecializationError>;
}
impl<T: SyscallGenericLibfunc> NoGenericArgsGenericLibfunc for T {
const STR_ID: &'static str = T::STR_ID;
fn specialize_signature(
&self,
context: &dyn SignatureSpecializationContext,
) -> Result<LibfuncSignature, SpecializationError> {
let gas_builtin_ty = context.get_concrete_type(GasBuiltinType::id(), &[])?;
let system_ty = context.get_concrete_type(SystemType::id(), &[])?;
let felt252_ty = context.get_concrete_type(Felt252Type::id(), &[])?;
let felt252_array_ty = context.get_wrapped_concrete_type(ArrayType::id(), felt252_ty)?;
let gb_output_info = OutputVarInfo {
ty: gas_builtin_ty.clone(),
ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
};
let system_output_info = OutputVarInfo::new_builtin(system_ty.clone(), 1);
Ok(LibfuncSignature {
param_signatures: chain!(
[
ParamSignature::new(gas_builtin_ty),
ParamSignature::new(system_ty).with_allow_add_const(),
],
T::input_tys(context)?.into_iter().map(ParamSignature::new)
)
.collect(),
branch_signatures: vec![
BranchSignature {
vars: chain!(
[
gb_output_info.clone(),
system_output_info.clone()
],
T::success_output_tys(context)?.into_iter().map(|ty| OutputVarInfo {
ty,
ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
})
)
.collect(),
ap_change: SierraApChange::Known { new_vars_only: false },
},
BranchSignature {
vars: vec![
gb_output_info,
system_output_info,
OutputVarInfo {
ty: felt252_array_ty,
ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
},
],
ap_change: SierraApChange::Known { new_vars_only: false },
},
],
fallthrough: Some(0),
})
}
}
#[derive(Default)]
pub struct ReplaceClassLibfunc {}
impl SyscallGenericLibfunc for ReplaceClassLibfunc {
const STR_ID: &'static str = "replace_class_syscall";
fn input_tys(
context: &dyn SignatureSpecializationContext,
) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
let class_hash_ty = context.get_concrete_type(ClassHashType::id(), &[])?;
Ok(vec![
class_hash_ty,
])
}
fn success_output_tys(
_context: &dyn SignatureSpecializationContext,
) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
Ok(vec![])
}
}
#[derive(Default)]
pub struct KeccakLibfunc {}
impl SyscallGenericLibfunc for KeccakLibfunc {
const STR_ID: &'static str = "keccak_syscall";
fn input_tys(
context: &dyn SignatureSpecializationContext,
) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
Ok(vec![
u64_span_ty(context)?,
])
}
fn success_output_tys(
context: &dyn SignatureSpecializationContext,
) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
Ok(vec![get_u256_type(context)?])
}
}
#[derive(Default)]
pub struct Sha256StateHandleType {}
impl NoGenericArgsGenericType for Sha256StateHandleType {
const ID: GenericTypeId = GenericTypeId::new_inline("Sha256StateHandle");
const STORABLE: bool = true;
const DUPLICATABLE: bool = true;
const DROPPABLE: bool = true;
const ZERO_SIZED: bool = false;
}
#[derive(Default)]
pub struct Sha256ProcessBlockLibfunc {}
impl SyscallGenericLibfunc for Sha256ProcessBlockLibfunc {
const STR_ID: &'static str = "sha256_process_block_syscall";
fn input_tys(
context: &dyn SignatureSpecializationContext,
) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
Ok(vec![
context.get_concrete_type(Sha256StateHandleType::id(), &[])?,
boxed_u32_fixed_array_ty(context, 16)?,
])
}
fn success_output_tys(
context: &dyn SignatureSpecializationContext,
) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
Ok(vec![context.get_concrete_type(Sha256StateHandleType::id(), &[])?])
}
}
#[derive(Default)]
pub struct Sha256StateHandleInitLibfunc {}
impl NoGenericArgsGenericLibfunc for Sha256StateHandleInitLibfunc {
const STR_ID: &'static str = "sha256_state_handle_init";
fn specialize_signature(
&self,
context: &dyn SignatureSpecializationContext,
) -> Result<LibfuncSignature, SpecializationError> {
Ok(LibfuncSignature::new_non_branch_ex(
vec![
ParamSignature::new(sha256_state_handle_unwrapped_type(context)?).with_allow_all(),
],
vec![OutputVarInfo {
ty: context.get_concrete_type(Sha256StateHandleType::id(), &[])?,
ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
}],
SierraApChange::Known { new_vars_only: false },
))
}
}
#[derive(Default)]
pub struct Sha256StateHandleDigestLibfunc {}
impl NoGenericArgsGenericLibfunc for Sha256StateHandleDigestLibfunc {
const STR_ID: &'static str = "sha256_state_handle_digest";
fn specialize_signature(
&self,
context: &dyn SignatureSpecializationContext,
) -> Result<LibfuncSignature, SpecializationError> {
Ok(LibfuncSignature::new_non_branch_ex(
vec![
ParamSignature::new(context.get_concrete_type(Sha256StateHandleType::id(), &[])?)
.with_allow_all(),
],
vec![OutputVarInfo {
ty: sha256_state_handle_unwrapped_type(context)?,
ref_info: OutputVarReferenceInfo::Deferred(DeferredOutputKind::Generic),
}],
SierraApChange::Known { new_vars_only: false },
))
}
}
pub fn sha256_state_handle_unwrapped_type(
context: &dyn SignatureSpecializationContext,
) -> Result<ConcreteTypeId, SpecializationError> {
boxed_u32_fixed_array_ty(context, 8)
}
fn boxed_u32_fixed_array_ty(
context: &dyn SignatureSpecializationContext,
size: i16,
) -> Result<ConcreteTypeId, SpecializationError> {
let ty = context.get_concrete_type(Uint32Type::id(), &[])?;
box_ty(context, fixed_size_array_ty(context, ty, size)?)
}
#[derive(Default)]
pub struct GetClassHashAtLibfunc {}
impl SyscallGenericLibfunc for GetClassHashAtLibfunc {
const STR_ID: &'static str = "get_class_hash_at_syscall";
fn input_tys(
context: &dyn SignatureSpecializationContext,
) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
Ok(vec![context.get_concrete_type(ContractAddressType::id(), &[])?])
}
fn success_output_tys(
context: &dyn SignatureSpecializationContext,
) -> Result<Vec<crate::ids::ConcreteTypeId>, SpecializationError> {
Ok(vec![context.get_concrete_type(ClassHashType::id(), &[])?])
}
}