iota_types/gas_model/
units_types.rs1use std::{
6 collections::BTreeMap,
7 ops::{Add, Bound},
8};
9
10use move_core_types::gas_algebra::{
11 GasQuantity, InternalGas, InternalGasUnit, ToUnit, ToUnitFractional,
12};
13use serde::{Deserialize, Serialize};
14
15pub enum GasUnit {}
16
17pub type Gas = GasQuantity<GasUnit>;
18
19impl ToUnit<InternalGasUnit> for GasUnit {
20 const MULTIPLIER: u64 = 1000;
21}
22
23impl ToUnitFractional<GasUnit> for InternalGasUnit {
24 const NOMINATOR: u64 = 1;
25 const DENOMINATOR: u64 = 1000;
26}
27
28pub const INSTRUCTION_TIER_DEFAULT: u64 = 1;
29
30pub const STACK_HEIGHT_TIER_DEFAULT: u64 = 1;
31pub const STACK_SIZE_TIER_DEFAULT: u64 = 1;
32
33#[derive(Clone, Debug, Serialize, PartialEq, Eq, Deserialize)]
35pub struct CostTable {
36 pub instruction_tiers: BTreeMap<u64, u64>,
37 pub stack_height_tiers: BTreeMap<u64, u64>,
38 pub stack_size_tiers: BTreeMap<u64, u64>,
39}
40
41impl CostTable {
42 fn get_current_and_future_tier(
43 tiers: &BTreeMap<u64, u64>,
44 current: u64,
45 default: u64,
46 ) -> (u64, Option<u64>) {
47 let current_cost = tiers
48 .get(¤t)
49 .or_else(|| tiers.range(..current).next_back().map(|(_, v)| v))
50 .unwrap_or(&default);
51 let next_tier_start = tiers
52 .range::<u64, _>((Bound::Excluded(current), Bound::Unbounded))
53 .next()
54 .map(|(next_tier_start, _)| *next_tier_start);
55 (*current_cost, next_tier_start)
56 }
57
58 pub fn instruction_tier(&self, instr_count: u64) -> (u64, Option<u64>) {
59 Self::get_current_and_future_tier(
60 &self.instruction_tiers,
61 instr_count,
62 INSTRUCTION_TIER_DEFAULT,
63 )
64 }
65
66 pub fn stack_height_tier(&self, stack_height: u64) -> (u64, Option<u64>) {
67 Self::get_current_and_future_tier(
68 &self.stack_height_tiers,
69 stack_height,
70 STACK_HEIGHT_TIER_DEFAULT,
71 )
72 }
73
74 pub fn stack_size_tier(&self, stack_size: u64) -> (u64, Option<u64>) {
75 Self::get_current_and_future_tier(
76 &self.stack_size_tiers,
77 stack_size,
78 STACK_SIZE_TIER_DEFAULT,
79 )
80 }
81}
82
83#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
90pub struct GasCost {
91 pub instruction_gas: u64,
92 pub memory_gas: u64,
93 pub stack_height_gas: u64,
94}
95
96impl GasCost {
97 pub fn new(instruction_gas: u64, memory_gas: u64, stack_height_gas: u64) -> Self {
98 Self {
99 instruction_gas,
100 memory_gas,
101 stack_height_gas,
102 }
103 }
104
105 #[inline]
107 pub fn total(&self) -> u64 {
108 self.instruction_gas
109 .add(self.memory_gas)
110 .add(self.stack_height_gas)
111 }
112
113 #[inline]
114 pub fn total_internal(&self) -> InternalGas {
115 GasQuantity::new(
116 self.instruction_gas
117 .add(self.memory_gas)
118 .add(self.stack_height_gas),
119 )
120 }
121}