use cairo_lang_sierra::extensions::gas::CostTokenType;
use cairo_lang_sierra::ids::ConcreteTypeId;
use cairo_lang_sierra::program::Function;
use cairo_lang_utils::collection_arithmetics::{add_maps, sub_maps};
use cairo_lang_utils::ordered_hash_map::OrderedHashMap;
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct ConstCost {
pub steps: i32,
pub holes: i32,
pub range_checks: i32,
}
impl ConstCost {
pub const fn cost(&self) -> i32 {
self.steps * 100 + self.holes * 10 + self.range_checks * 70
}
pub const fn steps(value: i32) -> Self {
Self { steps: value, holes: 0, range_checks: 0 }
}
pub const fn holes(value: i32) -> Self {
Self { holes: value, steps: 0, range_checks: 0 }
}
pub const fn range_checks(value: i32) -> Self {
Self { range_checks: value, steps: 0, holes: 0 }
}
}
impl ConstCost {
pub const fn add(self, rhs: Self) -> Self {
Self {
steps: self.steps + rhs.steps,
holes: self.holes + rhs.holes,
range_checks: self.range_checks + rhs.range_checks,
}
}
}
impl std::ops::Add for ConstCost {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
self.add(rhs)
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct PreCost(pub OrderedHashMap<CostTokenType, i32>);
impl PreCost {
pub fn builtin(token_type: CostTokenType) -> Self {
Self(OrderedHashMap::from_iter(([(token_type, 1)]).into_iter()))
}
}
impl std::ops::Add for PreCost {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
PreCost(add_maps(self.0, rhs.0))
}
}
impl std::ops::Sub for PreCost {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
PreCost(sub_maps(self.0, rhs.0))
}
}
#[derive(Clone)]
pub enum BranchCost {
Regular { const_cost: ConstCost, pre_cost: PreCost },
FunctionCall { const_cost: ConstCost, function: Function },
BranchAlign,
WithdrawGas { const_cost: ConstCost, success: bool, with_builtin_costs: bool },
RedepositGas,
}
impl From<ConstCost> for BranchCost {
fn from(value: ConstCost) -> Self {
BranchCost::Regular { const_cost: value, pre_cost: PreCost::default() }
}
}
pub trait CostInfoProvider {
fn type_size(&self, ty: &ConcreteTypeId) -> usize;
}