sui_adapter_latest/static_programmable_transactions/metering/
translation_meter.rs1use crate::gas_charger::GasCharger;
5use crate::static_programmable_transactions::loading::ast::{DeserializedPackage, PackagePayload};
6use sui_protocol_config::ProtocolConfig;
7use sui_types::error::ExecutionErrorTrait;
8use sui_types::execution_status::ExecutionErrorKind;
9
10pub struct TranslationMeter<'pc, 'gas> {
17 protocol_config: &'pc ProtocolConfig,
18 charger: &'gas mut GasCharger,
19}
20
21impl<'pc, 'gas> TranslationMeter<'pc, 'gas> {
22 pub fn new(
23 protocol_config: &'pc ProtocolConfig,
24 gas_charger: &'gas mut GasCharger,
25 ) -> TranslationMeter<'pc, 'gas> {
26 TranslationMeter {
27 protocol_config,
28 charger: gas_charger,
29 }
30 }
31
32 pub fn charge_base_inputs<E: ExecutionErrorTrait>(
33 &mut self,
34 num_inputs: usize,
35 ) -> Result<(), E> {
36 let amount = (num_inputs as u64)
37 .max(1)
38 .saturating_mul(self.protocol_config.translation_per_input_base_charge());
39 self.charge(amount)
40 }
41
42 pub fn charge_pure_input_bytes<E: ExecutionErrorTrait>(
43 &mut self,
44 num_bytes: usize,
45 ) -> Result<(), E> {
46 let amount = (num_bytes as u64).max(1).saturating_mul(
47 self.protocol_config
48 .translation_pure_input_per_byte_charge(),
49 );
50 self.charge(amount)
51 }
52
53 pub fn charge_base_command<E: ExecutionErrorTrait>(
54 &mut self,
55 num_args: usize,
56 ) -> Result<(), E> {
57 let amount = (num_args as u64)
58 .max(1)
59 .saturating_mul(self.protocol_config.translation_per_command_base_charge());
60 self.charge(amount)
61 }
62
63 pub fn charge_num_type_nodes<E: ExecutionErrorTrait>(
67 &mut self,
68 num_type_nodes: u64,
69 ) -> Result<(), E> {
70 let amount = num_type_nodes
71 .max(1)
72 .saturating_mul(self.protocol_config.translation_per_type_node_charge());
73 self.charge(amount)
74 }
75
76 pub fn charge_num_type_references<E: ExecutionErrorTrait>(
77 &mut self,
78 num_type_references: u64,
79 ) -> Result<(), E> {
80 let amount = self.reference_cost_formula(num_type_references.max(1))?;
81 let amount =
82 amount.saturating_mul(self.protocol_config.translation_per_reference_node_charge());
83 self.charge(amount)
84 }
85
86 pub fn charge_num_live_references<E: ExecutionErrorTrait>(
89 &mut self,
90 num_live_references: u64,
91 ) -> Result<(), E> {
92 let amount = self
93 .live_reference_cost_formula(num_live_references)
94 .saturating_mul(self.protocol_config.translation_per_live_reference_charge());
95 if amount == 0 {
96 return Ok(());
98 }
99 self.charge(amount)
100 }
101
102 pub fn charge_num_linkage_entries<E: ExecutionErrorTrait>(
103 &mut self,
104 num_linkage_entries: usize,
105 ) -> Result<(), E> {
106 let amount = (num_linkage_entries as u64)
107 .saturating_mul(self.protocol_config.translation_per_linkage_entry_charge())
108 .max(1);
109 self.charge(amount)
110 }
111
112 pub fn charge_package_load<E: ExecutionErrorTrait>(
113 &mut self,
114 payload: &PackagePayload,
115 ) -> Result<(), E> {
116 match payload {
117 PackagePayload::Serialized(_) => {
118 Ok(())
120 }
121 PackagePayload::Deserialized(DeserializedPackage { total_bytes, .. }) => {
122 self.charger.charge_publish_package(*total_bytes)?;
123 Ok(())
124 }
125 }
126 }
127
128 fn reference_cost_formula<E: ExecutionErrorTrait>(&self, n: u64) -> Result<u64, E> {
134 let Some(n_succ) = n.checked_add(1) else {
135 invariant_violation!("u64 overflow when calculating type reference cost")
136 };
137 Ok(n.saturating_mul(n_succ) / 2)
138 }
139
140 fn live_reference_cost_formula(&self, n: u64) -> u64 {
146 let product = n
147 .saturating_mul(n.saturating_add(1))
148 .saturating_mul(n.saturating_add(2));
149 product / 6
150 }
151
152 fn charge<E: ExecutionErrorTrait>(&mut self, amount: u64) -> Result<(), E> {
155 debug_assert!(amount > 0);
156 self.charger
157 .move_gas_status_mut()
158 .deduct_gas(amount.into())
159 .map_err(Self::gas_error)
160 }
161
162 fn gas_error<T, E>(e: T) -> E
163 where
164 T: Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
165 E: ExecutionErrorTrait,
166 {
167 E::new_with_source(ExecutionErrorKind::InsufficientGas, e)
168 }
169}