1use crate::parameter::Parameter;
2use crate::parameter_table::FeeComponent;
3use enum_map::{EnumMap, enum_map};
4use near_account_id::AccountType;
5use near_primitives_core::account::{AccessKey, GasKeyInfo};
6use near_primitives_core::errors::IntegerOverflowError;
7use near_primitives_core::trie_key::access_key_key_len;
8use near_primitives_core::types::{Balance, Compute, Gas, NonceIndex};
9use near_schema_checker_lib::ProtocolSchema;
10use num_rational::Rational32;
11
12#[derive(Debug, Clone, Hash, PartialEq, Eq)]
17pub struct Fee {
18 pub send_sir: FeeComponent,
21 pub send_not_sir: FeeComponent,
23 pub execution: FeeComponent,
25}
26
27impl Fee {
28 pub fn new(send_sir: u64, send_not_sir: u64, execution: u64) -> Self {
29 Self {
30 send_sir: FeeComponent::Gas(Gas::from_gas(send_sir)),
31 send_not_sir: FeeComponent::Gas(Gas::from_gas(send_not_sir)),
32 execution: FeeComponent::Gas(Gas::from_gas(execution)),
33 }
34 }
35
36 #[inline]
37 pub fn send_fee(&self, sir: bool) -> ParameterCost {
38 if sir { self.send_sir.cost() } else { self.send_not_sir.cost() }
39 }
40
41 pub fn exec_fee(&self) -> ParameterCost {
42 self.execution.cost()
43 }
44
45 pub fn min_send_and_exec_fee(&self) -> Gas {
47 std::cmp::min(self.send_sir.gas(), self.send_not_sir.gas())
48 .checked_add(self.execution.gas())
49 .unwrap()
50 }
51
52 fn test_value(value: u64, factor: u64) -> Self {
53 Self::test_value_detailed(value, value, value, factor)
54 }
55
56 fn test_value_detailed(
57 send_sir_cost: u64,
58 send_not_sir_cost: u64,
59 execution_cost: u64,
60 factor: u64,
61 ) -> Self {
62 Self {
63 send_sir: FeeComponent::GasAndCompute {
64 gas: Gas::from_gas(send_sir_cost),
65 compute: send_sir_cost * factor,
66 },
67 send_not_sir: FeeComponent::GasAndCompute {
68 gas: Gas::from_gas(send_not_sir_cost),
69 compute: send_not_sir_cost * factor,
70 },
71 execution: FeeComponent::GasAndCompute {
72 gas: Gas::from_gas(execution_cost),
73 compute: execution_cost * factor,
74 },
75 }
76 }
77}
78#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
79pub struct ParameterCost {
80 pub gas: Gas,
81 pub compute: Compute,
82}
83
84impl ParameterCost {
85 pub const ZERO: ParameterCost = ParameterCost { gas: Gas::ZERO, compute: 0 };
86
87 pub fn new(gas: Gas, compute: Compute) -> Self {
88 Self { gas, compute }
89 }
90
91 pub fn checked_add(self, rhs: Self) -> Option<Self> {
92 let gas = self.gas.checked_add(rhs.gas)?;
93 let compute = self.compute.checked_add(rhs.compute)?;
94 Some(Self { gas, compute })
95 }
96
97 pub fn checked_add_result(self, rhs: Self) -> Result<Self, IntegerOverflowError> {
98 self.checked_add(rhs).ok_or(IntegerOverflowError)
99 }
100
101 pub fn checked_sub(self, rhs: Self) -> Option<Self> {
102 let gas = self.gas.checked_sub(rhs.gas)?;
103 let compute = self.compute.checked_sub(rhs.compute)?;
104 Some(Self { gas, compute })
105 }
106
107 pub fn checked_mul(self, rhs: u64) -> Option<Self> {
108 let gas = self.gas.checked_mul(rhs)?;
109 let compute = self.compute.checked_mul(rhs)?;
110 Some(Self { gas, compute })
111 }
112}
113
114#[derive(Debug, Clone, Hash, PartialEq, Eq)]
115pub struct ExtCostsConfig {
116 pub costs: EnumMap<ExtCosts, ParameterCost>,
117}
118
119const SAFETY_MULTIPLIER: u64 = 3;
122
123impl ExtCostsConfig {
124 pub fn gas_cost(&self, param: ExtCosts) -> Gas {
125 self.costs[param].gas
126 }
127
128 pub fn compute_cost(&self, param: ExtCosts) -> Compute {
129 self.costs[param].compute
130 }
131
132 pub fn test_with_undercharging_factor(factor: u64) -> ExtCostsConfig {
135 let costs = enum_map! {
136 ExtCosts::base => SAFETY_MULTIPLIER * 88256037,
137 ExtCosts::contract_loading_base => SAFETY_MULTIPLIER * 11815321,
138 ExtCosts::contract_loading_bytes => SAFETY_MULTIPLIER * 72250,
139 ExtCosts::read_memory_base => SAFETY_MULTIPLIER * 869954400,
140 ExtCosts::read_memory_byte => SAFETY_MULTIPLIER * 1267111,
141 ExtCosts::write_memory_base => SAFETY_MULTIPLIER * 934598287,
142 ExtCosts::write_memory_byte => SAFETY_MULTIPLIER * 907924,
143 ExtCosts::read_register_base => SAFETY_MULTIPLIER * 839055062,
144 ExtCosts::read_register_byte => SAFETY_MULTIPLIER * 32854,
145 ExtCosts::write_register_base => SAFETY_MULTIPLIER * 955174162,
146 ExtCosts::write_register_byte => SAFETY_MULTIPLIER * 1267188,
147 ExtCosts::utf8_decoding_base => SAFETY_MULTIPLIER * 1037259687,
148 ExtCosts::utf8_decoding_byte => SAFETY_MULTIPLIER * 97193493,
149 ExtCosts::utf16_decoding_base => SAFETY_MULTIPLIER * 1181104350,
150 ExtCosts::utf16_decoding_byte => SAFETY_MULTIPLIER * 54525831,
151 ExtCosts::sha256_base => SAFETY_MULTIPLIER * 1513656750,
152 ExtCosts::sha256_byte => SAFETY_MULTIPLIER * 8039117,
153 ExtCosts::keccak256_base => SAFETY_MULTIPLIER * 1959830425,
154 ExtCosts::keccak256_byte => SAFETY_MULTIPLIER * 7157035,
155 ExtCosts::keccak512_base => SAFETY_MULTIPLIER * 1937129412,
156 ExtCosts::keccak512_byte => SAFETY_MULTIPLIER * 12216567,
157 ExtCosts::ripemd160_base => SAFETY_MULTIPLIER * 284558362,
158 ExtCosts::ed25519_verify_base => SAFETY_MULTIPLIER * 1513656750,
159 ExtCosts::ed25519_verify_byte => SAFETY_MULTIPLIER * 7157035,
160 ExtCosts::ripemd160_block => SAFETY_MULTIPLIER * 226702528,
161 ExtCosts::ecrecover_base => SAFETY_MULTIPLIER * 1121789875000,
162 ExtCosts::p256_verify_base => SAFETY_MULTIPLIER * 433_333_333_333,
163 ExtCosts::p256_verify_byte => SAFETY_MULTIPLIER * 4_333_333,
164 ExtCosts::log_base => SAFETY_MULTIPLIER * 1181104350,
165 ExtCosts::log_byte => SAFETY_MULTIPLIER * 4399597,
166 ExtCosts::storage_write_base => SAFETY_MULTIPLIER * 21398912000,
167 ExtCosts::storage_write_key_byte => SAFETY_MULTIPLIER * 23494289,
168 ExtCosts::storage_write_value_byte => SAFETY_MULTIPLIER * 10339513,
169 ExtCosts::storage_write_evicted_byte => SAFETY_MULTIPLIER * 10705769,
170 ExtCosts::storage_read_base => SAFETY_MULTIPLIER * 18785615250,
171 ExtCosts::storage_read_key_byte => SAFETY_MULTIPLIER * 10317511,
172 ExtCosts::storage_read_value_byte => SAFETY_MULTIPLIER * 1870335,
173 ExtCosts::storage_large_read_overhead_base => 0,
174 ExtCosts::storage_large_read_overhead_byte => 0,
175 ExtCosts::storage_remove_base => SAFETY_MULTIPLIER * 17824343500,
176 ExtCosts::storage_remove_key_byte => SAFETY_MULTIPLIER * 12740128,
177 ExtCosts::storage_remove_ret_value_byte => SAFETY_MULTIPLIER * 3843852,
178 ExtCosts::storage_has_key_base => SAFETY_MULTIPLIER * 18013298875,
179 ExtCosts::storage_has_key_byte => SAFETY_MULTIPLIER * 10263615,
180 ExtCosts::storage_iter_create_prefix_base => 0,
183 ExtCosts::storage_iter_create_prefix_byte => 0,
184 ExtCosts::storage_iter_create_range_base => 0,
185 ExtCosts::storage_iter_create_from_byte => 0,
186 ExtCosts::storage_iter_create_to_byte => 0,
187 ExtCosts::storage_iter_next_base => 0,
188 ExtCosts::storage_iter_next_key_byte => 0,
189 ExtCosts::storage_iter_next_value_byte => 0,
190 ExtCosts::touching_trie_node => SAFETY_MULTIPLIER * 5367318642,
191 ExtCosts::read_cached_trie_node => SAFETY_MULTIPLIER * 760_000_000,
192 ExtCosts::promise_and_base => SAFETY_MULTIPLIER * 488337800,
193 ExtCosts::promise_and_per_promise => SAFETY_MULTIPLIER * 1817392,
194 ExtCosts::promise_return => SAFETY_MULTIPLIER * 186717462,
195 ExtCosts::validator_stake_base => SAFETY_MULTIPLIER * 303944908800,
196 ExtCosts::validator_total_stake_base => SAFETY_MULTIPLIER * 303944908800,
197 ExtCosts::alt_bn128_g1_multiexp_base => 713_000_000_000,
198 ExtCosts::alt_bn128_g1_multiexp_element => 320_000_000_000,
199 ExtCosts::alt_bn128_pairing_check_base => 9_686_000_000_000,
200 ExtCosts::alt_bn128_pairing_check_element => 5_102_000_000_000,
201 ExtCosts::alt_bn128_g1_sum_base => 3_000_000_000,
202 ExtCosts::alt_bn128_g1_sum_element => 5_000_000_000,
203 ExtCosts::bls12381_p1_sum_base => SAFETY_MULTIPLIER * 5_500_000_000,
204 ExtCosts::bls12381_p1_sum_element => SAFETY_MULTIPLIER * 2_000_000_000,
205 ExtCosts::bls12381_p2_sum_base => SAFETY_MULTIPLIER * 6_200_000_000,
206 ExtCosts::bls12381_p2_sum_element => SAFETY_MULTIPLIER * 5_000_000_000,
207 ExtCosts::bls12381_g1_multiexp_base => SAFETY_MULTIPLIER * 5_500_000_000,
208 ExtCosts::bls12381_g1_multiexp_element => SAFETY_MULTIPLIER * 310_000_000_000,
209 ExtCosts::bls12381_g2_multiexp_base => SAFETY_MULTIPLIER * 6_200_000_000,
210 ExtCosts::bls12381_g2_multiexp_element => SAFETY_MULTIPLIER * 665_000_000_000,
211 ExtCosts::bls12381_map_fp_to_g1_base => SAFETY_MULTIPLIER * 500_000_000,
212 ExtCosts::bls12381_map_fp_to_g1_element => SAFETY_MULTIPLIER * 84_000_000_000,
213 ExtCosts::bls12381_map_fp2_to_g2_base => SAFETY_MULTIPLIER * 500_000_000,
214 ExtCosts::bls12381_map_fp2_to_g2_element => SAFETY_MULTIPLIER * 300_000_000_000,
215 ExtCosts::bls12381_pairing_base => SAFETY_MULTIPLIER * 710_000_000_000,
216 ExtCosts::bls12381_pairing_element => SAFETY_MULTIPLIER * 710_000_000_000,
217 ExtCosts::bls12381_p1_decompress_base => SAFETY_MULTIPLIER * 500_000_000,
218 ExtCosts::bls12381_p1_decompress_element => SAFETY_MULTIPLIER * 27_000_000_000,
219 ExtCosts::bls12381_p2_decompress_base => SAFETY_MULTIPLIER * 500_000_000,
220 ExtCosts::bls12381_p2_decompress_element => SAFETY_MULTIPLIER * 55_000_000_000,
221 ExtCosts::yield_create_base => 300_000_000_000_000,
223 ExtCosts::yield_create_byte => 300_000_000_000_000,
224 ExtCosts::yield_create_with_id_base => 300_000_000_000_000,
225 ExtCosts::yield_resume_base => 300_000_000_000_000,
226 ExtCosts::yield_resume_byte => 300_000_000_000_000,
227 }
228 .map(|_, value| ParameterCost { gas: Gas::from_gas(value), compute: value * factor });
229 ExtCostsConfig { costs }
230 }
231
232 pub fn test() -> ExtCostsConfig {
234 Self::test_with_undercharging_factor(1)
235 }
236}
237
238#[derive(
243 Copy,
244 Clone,
245 Hash,
246 PartialEq,
247 Eq,
248 Debug,
249 PartialOrd,
250 Ord,
251 strum::Display,
252 strum::EnumIter,
253 enum_map::Enum,
254 ProtocolSchema,
255)]
256#[allow(non_camel_case_types)]
257pub enum ExtCosts {
258 base = 0,
259 contract_loading_base = 1,
260 contract_loading_bytes = 2,
261 read_memory_base = 3,
262 read_memory_byte = 4,
263 write_memory_base = 5,
264 write_memory_byte = 6,
265 read_register_base = 7,
266 read_register_byte = 8,
267 write_register_base = 9,
268 write_register_byte = 10,
269 utf8_decoding_base = 11,
270 utf8_decoding_byte = 12,
271 utf16_decoding_base = 13,
272 utf16_decoding_byte = 14,
273 sha256_base = 15,
274 sha256_byte = 16,
275 keccak256_base = 17,
276 keccak256_byte = 18,
277 keccak512_base = 19,
278 keccak512_byte = 20,
279 ripemd160_base = 21,
280 ripemd160_block = 22,
281 ecrecover_base = 23,
282 log_base = 24,
283 log_byte = 25,
284 storage_write_base = 26,
285 storage_write_key_byte = 27,
286 storage_write_value_byte = 28,
287 storage_write_evicted_byte = 29,
288 storage_read_base = 30,
289 storage_read_key_byte = 31,
290 storage_read_value_byte = 32,
291 storage_remove_base = 33,
292 storage_remove_key_byte = 34,
293 storage_remove_ret_value_byte = 35,
294 storage_has_key_base = 36,
295 storage_has_key_byte = 37,
296 storage_iter_create_prefix_base = 38,
297 storage_iter_create_prefix_byte = 39,
298 storage_iter_create_range_base = 40,
299 storage_iter_create_from_byte = 41,
300 storage_iter_create_to_byte = 42,
301 storage_iter_next_base = 43,
302 storage_iter_next_key_byte = 44,
303 storage_iter_next_value_byte = 45,
304 touching_trie_node = 46,
305 read_cached_trie_node = 47,
306 promise_and_base = 48,
307 promise_and_per_promise = 49,
308 promise_return = 50,
309 validator_stake_base = 51,
310 validator_total_stake_base = 52,
311 alt_bn128_g1_multiexp_base = 53,
312 alt_bn128_g1_multiexp_element = 54,
313 alt_bn128_pairing_check_base = 55,
314 alt_bn128_pairing_check_element = 56,
315 alt_bn128_g1_sum_base = 57,
316 alt_bn128_g1_sum_element = 58,
317 ed25519_verify_base = 59,
318 ed25519_verify_byte = 60,
319 yield_create_base = 61,
320 yield_create_byte = 62,
321 yield_resume_base = 63,
322 yield_resume_byte = 64,
323 bls12381_p1_sum_base = 65,
324 bls12381_p1_sum_element = 66,
325 bls12381_p2_sum_base = 67,
326 bls12381_p2_sum_element = 68,
327 bls12381_g1_multiexp_base = 69,
328 bls12381_g1_multiexp_element = 70,
329 bls12381_g2_multiexp_base = 71,
330 bls12381_g2_multiexp_element = 72,
331 bls12381_map_fp_to_g1_base = 73,
332 bls12381_map_fp_to_g1_element = 74,
333 bls12381_map_fp2_to_g2_base = 75,
334 bls12381_map_fp2_to_g2_element = 76,
335 bls12381_pairing_base = 77,
336 bls12381_pairing_element = 78,
337 bls12381_p1_decompress_base = 79,
338 bls12381_p1_decompress_element = 80,
339 bls12381_p2_decompress_base = 81,
340 bls12381_p2_decompress_element = 82,
341 storage_large_read_overhead_base = 83,
342 storage_large_read_overhead_byte = 84,
343 p256_verify_base = 85,
344 p256_verify_byte = 86,
345 yield_create_with_id_base = 87,
346}
347
348#[derive(
350 Copy,
351 Clone,
352 Hash,
353 PartialEq,
354 Eq,
355 Debug,
356 PartialOrd,
357 Ord,
358 strum::Display,
359 strum::EnumIter,
360 enum_map::Enum,
361 ProtocolSchema,
362)]
363#[allow(non_camel_case_types)]
364pub enum ActionCosts {
365 create_account = 0,
366 delete_account = 1,
367 deploy_contract_base = 2,
368 deploy_contract_byte = 3,
369 function_call_base = 4,
370 function_call_byte = 5,
371 transfer = 6,
372 stake = 7,
373 add_full_access_key = 8,
374 add_function_call_key_base = 9,
375 add_function_call_key_byte = 10,
376 delete_key = 11,
377 new_action_receipt = 12,
378 new_data_receipt_base = 13,
379 new_data_receipt_byte = 14,
380 delegate = 15,
381 deploy_global_contract_base = 16,
382 deploy_global_contract_byte = 17,
383 use_global_contract_base = 18,
384 use_global_contract_byte = 19,
385 deterministic_state_init_base = 20,
386 deterministic_state_init_byte = 21,
387 deterministic_state_init_entry = 22,
388 gas_key_transfer_base = 23,
389 gas_key_byte = 24,
390 gas_key_nonce_write_base = 25,
391}
392
393impl ExtCosts {
394 pub fn gas(self, config: &ExtCostsConfig) -> Gas {
395 config.gas_cost(self)
396 }
397
398 pub fn compute(self, config: &ExtCostsConfig) -> Compute {
399 config.compute_cost(self)
400 }
401
402 pub fn param(&self) -> Parameter {
403 match self {
404 ExtCosts::base => Parameter::WasmBase,
405 ExtCosts::contract_loading_base => Parameter::WasmContractLoadingBase,
406 ExtCosts::contract_loading_bytes => Parameter::WasmContractLoadingBytes,
407 ExtCosts::read_memory_base => Parameter::WasmReadMemoryBase,
408 ExtCosts::read_memory_byte => Parameter::WasmReadMemoryByte,
409 ExtCosts::write_memory_base => Parameter::WasmWriteMemoryBase,
410 ExtCosts::write_memory_byte => Parameter::WasmWriteMemoryByte,
411 ExtCosts::read_register_base => Parameter::WasmReadRegisterBase,
412 ExtCosts::read_register_byte => Parameter::WasmReadRegisterByte,
413 ExtCosts::write_register_base => Parameter::WasmWriteRegisterBase,
414 ExtCosts::write_register_byte => Parameter::WasmWriteRegisterByte,
415 ExtCosts::utf8_decoding_base => Parameter::WasmUtf8DecodingBase,
416 ExtCosts::utf8_decoding_byte => Parameter::WasmUtf8DecodingByte,
417 ExtCosts::utf16_decoding_base => Parameter::WasmUtf16DecodingBase,
418 ExtCosts::utf16_decoding_byte => Parameter::WasmUtf16DecodingByte,
419 ExtCosts::sha256_base => Parameter::WasmSha256Base,
420 ExtCosts::sha256_byte => Parameter::WasmSha256Byte,
421 ExtCosts::keccak256_base => Parameter::WasmKeccak256Base,
422 ExtCosts::keccak256_byte => Parameter::WasmKeccak256Byte,
423 ExtCosts::keccak512_base => Parameter::WasmKeccak512Base,
424 ExtCosts::keccak512_byte => Parameter::WasmKeccak512Byte,
425 ExtCosts::ripemd160_base => Parameter::WasmRipemd160Base,
426 ExtCosts::ripemd160_block => Parameter::WasmRipemd160Block,
427 ExtCosts::ecrecover_base => Parameter::WasmEcrecoverBase,
428 ExtCosts::ed25519_verify_base => Parameter::WasmEd25519VerifyBase,
429 ExtCosts::ed25519_verify_byte => Parameter::WasmEd25519VerifyByte,
430 ExtCosts::p256_verify_base => Parameter::WasmP256VerifyBase,
431 ExtCosts::p256_verify_byte => Parameter::WasmP256VerifyByte,
432 ExtCosts::log_base => Parameter::WasmLogBase,
433 ExtCosts::log_byte => Parameter::WasmLogByte,
434 ExtCosts::storage_write_base => Parameter::WasmStorageWriteBase,
435 ExtCosts::storage_write_key_byte => Parameter::WasmStorageWriteKeyByte,
436 ExtCosts::storage_write_value_byte => Parameter::WasmStorageWriteValueByte,
437 ExtCosts::storage_write_evicted_byte => Parameter::WasmStorageWriteEvictedByte,
438 ExtCosts::storage_read_base => Parameter::WasmStorageReadBase,
439 ExtCosts::storage_read_key_byte => Parameter::WasmStorageReadKeyByte,
440 ExtCosts::storage_read_value_byte => Parameter::WasmStorageReadValueByte,
441 ExtCosts::storage_large_read_overhead_base => {
442 Parameter::WasmStorageLargeReadOverheadBase
443 }
444 ExtCosts::storage_large_read_overhead_byte => {
445 Parameter::WasmStorageLargeReadOverheadByte
446 }
447 ExtCosts::storage_remove_base => Parameter::WasmStorageRemoveBase,
448 ExtCosts::storage_remove_key_byte => Parameter::WasmStorageRemoveKeyByte,
449 ExtCosts::storage_remove_ret_value_byte => Parameter::WasmStorageRemoveRetValueByte,
450 ExtCosts::storage_has_key_base => Parameter::WasmStorageHasKeyBase,
451 ExtCosts::storage_has_key_byte => Parameter::WasmStorageHasKeyByte,
452 ExtCosts::storage_iter_create_prefix_base => Parameter::WasmStorageIterCreatePrefixBase,
453 ExtCosts::storage_iter_create_prefix_byte => Parameter::WasmStorageIterCreatePrefixByte,
454 ExtCosts::storage_iter_create_range_base => Parameter::WasmStorageIterCreateRangeBase,
455 ExtCosts::storage_iter_create_from_byte => Parameter::WasmStorageIterCreateFromByte,
456 ExtCosts::storage_iter_create_to_byte => Parameter::WasmStorageIterCreateToByte,
457 ExtCosts::storage_iter_next_base => Parameter::WasmStorageIterNextBase,
458 ExtCosts::storage_iter_next_key_byte => Parameter::WasmStorageIterNextKeyByte,
459 ExtCosts::storage_iter_next_value_byte => Parameter::WasmStorageIterNextValueByte,
460 ExtCosts::touching_trie_node => Parameter::WasmTouchingTrieNode,
461 ExtCosts::read_cached_trie_node => Parameter::WasmReadCachedTrieNode,
462 ExtCosts::promise_and_base => Parameter::WasmPromiseAndBase,
463 ExtCosts::promise_and_per_promise => Parameter::WasmPromiseAndPerPromise,
464 ExtCosts::promise_return => Parameter::WasmPromiseReturn,
465 ExtCosts::validator_stake_base => Parameter::WasmValidatorStakeBase,
466 ExtCosts::validator_total_stake_base => Parameter::WasmValidatorTotalStakeBase,
467 ExtCosts::alt_bn128_g1_multiexp_base => Parameter::WasmAltBn128G1MultiexpBase,
468 ExtCosts::alt_bn128_g1_multiexp_element => Parameter::WasmAltBn128G1MultiexpElement,
469 ExtCosts::alt_bn128_pairing_check_base => Parameter::WasmAltBn128PairingCheckBase,
470 ExtCosts::alt_bn128_pairing_check_element => Parameter::WasmAltBn128PairingCheckElement,
471 ExtCosts::alt_bn128_g1_sum_base => Parameter::WasmAltBn128G1SumBase,
472 ExtCosts::alt_bn128_g1_sum_element => Parameter::WasmAltBn128G1SumElement,
473 ExtCosts::yield_create_base => Parameter::WasmYieldCreateBase,
474 ExtCosts::yield_create_byte => Parameter::WasmYieldCreateByte,
475 ExtCosts::yield_create_with_id_base => Parameter::WasmYieldCreateWithIdBase,
476 ExtCosts::yield_resume_base => Parameter::WasmYieldResumeBase,
477 ExtCosts::yield_resume_byte => Parameter::WasmYieldResumeByte,
478 ExtCosts::bls12381_p1_sum_base => Parameter::WasmBls12381P1SumBase,
479 ExtCosts::bls12381_p1_sum_element => Parameter::WasmBls12381P1SumElement,
480 ExtCosts::bls12381_p2_sum_base => Parameter::WasmBls12381P2SumBase,
481 ExtCosts::bls12381_p2_sum_element => Parameter::WasmBls12381P2SumElement,
482 ExtCosts::bls12381_g1_multiexp_base => Parameter::WasmBls12381G1MultiexpBase,
483 ExtCosts::bls12381_g1_multiexp_element => Parameter::WasmBls12381G1MultiexpElement,
484 ExtCosts::bls12381_g2_multiexp_base => Parameter::WasmBls12381G2MultiexpBase,
485 ExtCosts::bls12381_g2_multiexp_element => Parameter::WasmBls12381G2MultiexpElement,
486 ExtCosts::bls12381_map_fp_to_g1_base => Parameter::WasmBls12381MapFpToG1Base,
487 ExtCosts::bls12381_map_fp_to_g1_element => Parameter::WasmBls12381MapFpToG1Element,
488 ExtCosts::bls12381_map_fp2_to_g2_base => Parameter::WasmBls12381MapFp2ToG2Base,
489 ExtCosts::bls12381_map_fp2_to_g2_element => Parameter::WasmBls12381MapFp2ToG2Element,
490 ExtCosts::bls12381_pairing_base => Parameter::WasmBls12381PairingBase,
491 ExtCosts::bls12381_pairing_element => Parameter::WasmBls12381PairingElement,
492 ExtCosts::bls12381_p1_decompress_base => Parameter::WasmBls12381P1DecompressBase,
493 ExtCosts::bls12381_p1_decompress_element => Parameter::WasmBls12381P1DecompressElement,
494 ExtCosts::bls12381_p2_decompress_base => Parameter::WasmBls12381P2DecompressBase,
495 ExtCosts::bls12381_p2_decompress_element => Parameter::WasmBls12381P2DecompressElement,
496 }
497 }
498}
499
500#[derive(Copy, Clone, Hash, PartialEq, Eq, Debug, enum_map::Enum)]
511pub enum SignatureKind {
512 Ed25519,
513 Secp256k1,
514 MlDsa65,
515}
516
517#[derive(Debug, Clone, Hash, PartialEq, Eq)]
518pub struct RuntimeFeesConfig {
519 pub action_fees: EnumMap<ActionCosts, Fee>,
521
522 pub storage_usage_config: StorageUsageConfig,
524
525 pub burnt_gas_reward: Rational32,
527
528 pub pessimistic_gas_price_inflation_ratio: Rational32,
530
531 pub gas_refund_penalty: Rational32,
538 pub min_gas_refund_penalty: Gas,
545
546 pub deploy_global_contract_execution_base: Compute,
549 pub deploy_global_contract_execution_per_byte: Compute,
552
553 pub signature_verification_costs: EnumMap<SignatureKind, ParameterCost>,
564}
565
566#[derive(Debug, Clone, Hash, PartialEq, Eq)]
568pub struct StorageUsageConfig {
569 pub storage_amount_per_byte: Balance,
572 pub num_bytes_account: u64,
574 pub num_extra_bytes_record: u64,
576 pub global_contract_storage_amount_per_byte: Balance,
578}
579
580impl RuntimeFeesConfig {
581 pub fn fee(&self, cost: ActionCosts) -> &Fee {
583 &self.action_fees[cost]
584 }
585
586 pub fn test_with_undercharging_factor(factor: u64) -> Self {
589 let create_account_fee =
595 if near_primitives_core::version::ProtocolFeature::AccountCostIncrease
596 .enabled(near_primitives_core::version::PROTOCOL_VERSION)
597 {
598 Fee::test_value_detailed(
599 500_000_000_000,
600 500_000_000_000,
601 7_200_000_000_000,
602 factor,
603 )
604 } else {
605 Fee::test_value(3_850_000_000_000, factor)
606 };
607 Self {
608 storage_usage_config: StorageUsageConfig::test(),
609 burnt_gas_reward: Rational32::new(3, 10),
610 pessimistic_gas_price_inflation_ratio: Rational32::new(103, 100),
611 gas_refund_penalty: Rational32::new(5, 100),
612 min_gas_refund_penalty: Gas::from_teragas(1),
613 action_fees: enum_map::enum_map! {
614 ActionCosts::create_account => create_account_fee.clone(),
615 ActionCosts::delete_account => Fee::test_value(147489000000, factor),
616 ActionCosts::deploy_contract_base => Fee::test_value(184765750000, factor),
617 ActionCosts::deploy_contract_byte => Fee::test_value(6812999, factor),
618 ActionCosts::function_call_base => Fee::test_value(2319861500000, factor),
619 ActionCosts::function_call_byte => Fee::test_value(2235934, factor),
620 ActionCosts::transfer => Fee::test_value(115123062500, factor),
621 ActionCosts::stake => Fee::new(141715687500, 141715687500, 102217625000),
622 ActionCosts::add_full_access_key => Fee::test_value(101765125000, factor),
623 ActionCosts::add_function_call_key_base => Fee::test_value(102217625000, factor),
624 ActionCosts::add_function_call_key_byte => Fee::test_value(1925331, factor),
625 ActionCosts::delete_key => Fee::test_value(94946625000, factor),
626 ActionCosts::new_action_receipt => Fee::test_value(108059500000, factor),
627 ActionCosts::new_data_receipt_base => Fee::test_value(4697339419375, factor),
628 ActionCosts::new_data_receipt_byte => Fee::test_value(59357464, factor),
629 ActionCosts::delegate => Fee::test_value(200_000_000_000, factor),
630 ActionCosts::deploy_global_contract_base => Fee::test_value(184_765_750_000, factor),
631 ActionCosts::deploy_global_contract_byte => Fee::new(6_812_999, 6_812_999, 70_000_000),
632 ActionCosts::use_global_contract_base => Fee::test_value(184_765_750_000, factor),
633 ActionCosts::use_global_contract_byte => Fee::new(6_812_999, 47_683_715, 64_572_944),
634 ActionCosts::deterministic_state_init_base => Fee::new(3_850_000_000_000, 3_850_000_000_000, 4_080_000_000_000),
635 ActionCosts::deterministic_state_init_byte => Fee::new(72_000_000, 72_000_000, 70_000_000),
636 ActionCosts::deterministic_state_init_entry => Fee::new(0, 0, 200_000_000_000),
637 ActionCosts::gas_key_transfer_base => Fee::new(115_123_062_500, 115_123_062_500, 235_676_644_250),
638 ActionCosts::gas_key_byte => Fee::new(59_357_464, 59_357_464, 101_435_400),
639 ActionCosts::gas_key_nonce_write_base => Fee::new(0, 0, 64_196_736_000),
640 },
641 deploy_global_contract_execution_base: 0,
642 deploy_global_contract_execution_per_byte: 0,
643 signature_verification_costs: enum_map::enum_map! { _ => ParameterCost::ZERO },
644 }
645 }
646
647 pub fn test() -> RuntimeFeesConfig {
649 Self::test_with_undercharging_factor(1)
650 }
651
652 pub fn free() -> Self {
653 Self {
654 action_fees: enum_map::enum_map! {
655 _ => Fee::new(0, 0, 0)
656 },
657 storage_usage_config: StorageUsageConfig::free(),
658 burnt_gas_reward: Rational32::from_integer(0),
659 pessimistic_gas_price_inflation_ratio: Rational32::from_integer(0),
660 gas_refund_penalty: Rational32::from_integer(0),
661 min_gas_refund_penalty: Gas::ZERO,
662 deploy_global_contract_execution_base: 0,
663 deploy_global_contract_execution_per_byte: 0,
664 signature_verification_costs: enum_map::enum_map! { _ => ParameterCost::ZERO },
665 }
666 }
667
668 pub fn min_receipt_with_function_call_gas(&self) -> Gas {
673 self.fee(ActionCosts::new_action_receipt)
674 .min_send_and_exec_fee()
675 .checked_add(self.fee(ActionCosts::function_call_base).min_send_and_exec_fee())
676 .unwrap()
677 }
678
679 pub fn gas_penalty_for_gas_refund(&self, gas_refund: Gas) -> Gas {
684 let relative_cost = Gas::from_gas(
685 (u128::from(gas_refund.as_gas()) * *self.gas_refund_penalty.numer() as u128
686 / *self.gas_refund_penalty.denom() as u128)
687 .try_into()
688 .unwrap(),
689 );
690
691 let penalty = std::cmp::max(relative_cost, self.min_gas_refund_penalty);
692 std::cmp::min(penalty, gas_refund)
693 }
694}
695
696impl StorageUsageConfig {
697 pub fn test() -> Self {
698 Self {
699 num_bytes_account: 100,
700 num_extra_bytes_record: 40,
701 storage_amount_per_byte: Balance::from_yoctonear(909 * 100_000_000_000_000_000),
702 global_contract_storage_amount_per_byte: Balance::from_yoctonear(
703 100_000_000_000_000_000_000,
704 ),
705 }
706 }
707
708 pub(crate) fn free() -> StorageUsageConfig {
709 Self {
710 num_bytes_account: 0,
711 num_extra_bytes_record: 0,
712 storage_amount_per_byte: Balance::ZERO,
713 global_contract_storage_amount_per_byte: Balance::ZERO,
714 }
715 }
716}
717
718pub fn transfer_exec_fee(
723 cfg: &RuntimeFeesConfig,
724 eth_implicit_accounts_enabled: bool,
725 receiver_account_type: AccountType,
726) -> ParameterCost {
727 let transfer_fee = cfg.fee(ActionCosts::transfer).exec_fee();
728 match (eth_implicit_accounts_enabled, receiver_account_type) {
729 (_, AccountType::NamedAccount) => transfer_fee,
731 (false, AccountType::EthImplicitAccount) => transfer_fee,
733 (true, AccountType::EthImplicitAccount) => {
735 transfer_fee.checked_add(cfg.fee(ActionCosts::create_account).exec_fee()).unwrap()
736 }
737 (_, AccountType::NearImplicitAccount) => transfer_fee
739 .checked_add(cfg.fee(ActionCosts::create_account).exec_fee())
740 .unwrap()
741 .checked_add(cfg.fee(ActionCosts::add_full_access_key).exec_fee())
742 .unwrap(),
743 (_, AccountType::NearDeterministicAccount) => {
745 transfer_fee.checked_add(cfg.fee(ActionCosts::create_account).exec_fee()).unwrap()
746 }
747 }
748}
749
750pub fn transfer_send_fee(
751 cfg: &RuntimeFeesConfig,
752 sender_is_receiver: bool,
753 eth_implicit_accounts_enabled: bool,
754 receiver_account_type: AccountType,
755) -> ParameterCost {
756 let transfer_fee = cfg.fee(ActionCosts::transfer).send_fee(sender_is_receiver);
757 match (eth_implicit_accounts_enabled, receiver_account_type) {
758 (_, AccountType::NamedAccount) => transfer_fee,
760 (false, AccountType::EthImplicitAccount) => transfer_fee,
762 (true, AccountType::EthImplicitAccount) => transfer_fee
764 .checked_add(cfg.fee(ActionCosts::create_account).send_fee(sender_is_receiver))
765 .unwrap(),
766 (_, AccountType::NearImplicitAccount) => transfer_fee
768 .checked_add(cfg.fee(ActionCosts::create_account).send_fee(sender_is_receiver))
769 .unwrap()
770 .checked_add(cfg.fee(ActionCosts::add_full_access_key).send_fee(sender_is_receiver))
771 .unwrap(),
772 (_, AccountType::NearDeterministicAccount) => transfer_fee
774 .checked_add(cfg.fee(ActionCosts::create_account).send_fee(sender_is_receiver))
775 .unwrap(),
776 }
777}
778
779pub struct GasKeyTransferFee {
782 pub base: ParameterCost,
783 pub per_byte: ParameterCost,
784}
785
786impl GasKeyTransferFee {
787 pub fn total(&self) -> ParameterCost {
788 self.base.checked_add(self.per_byte).unwrap()
789 }
790}
791
792pub fn gas_key_transfer_send_fee(
795 cfg: &RuntimeFeesConfig,
796 sender_is_receiver: bool,
797 public_key_len: usize,
798) -> GasKeyTransferFee {
799 let base = cfg.fee(ActionCosts::gas_key_transfer_base).send_fee(sender_is_receiver);
800 let per_byte = cfg
801 .fee(ActionCosts::gas_key_byte)
802 .send_fee(sender_is_receiver)
803 .checked_mul(public_key_len as u64)
804 .unwrap();
805 GasKeyTransferFee { base, per_byte }
806}
807
808pub fn gas_key_transfer_exec_fee(
812 cfg: &RuntimeFeesConfig,
813 account_id_len: usize,
814 public_key_len: usize,
815) -> GasKeyTransferFee {
816 let base = cfg.fee(ActionCosts::gas_key_transfer_base).exec_fee();
817 let trie_key_len = access_key_key_len(account_id_len, public_key_len);
818 let estimated_value_len = AccessKey::min_gas_key_borsh_len();
819 let per_byte = cfg
820 .fee(ActionCosts::gas_key_byte)
821 .exec_fee()
822 .checked_mul((trie_key_len + estimated_value_len) as u64)
823 .unwrap();
824 GasKeyTransferFee { base, per_byte }
825}
826
827pub struct GasKeyAddFee {
831 pub base: ParameterCost,
832 pub per_byte: ParameterCost,
833}
834
835impl GasKeyAddFee {
836 pub fn total(&self) -> ParameterCost {
837 self.base.checked_add(self.per_byte).unwrap()
838 }
839}
840
841pub fn gas_key_add_key_send_fee(
845 cfg: &RuntimeFeesConfig,
846 sender_is_receiver: bool,
847) -> ParameterCost {
848 cfg.fee(ActionCosts::gas_key_byte)
849 .send_fee(sender_is_receiver)
850 .checked_mul(GasKeyInfo::borsh_len() as u64)
851 .unwrap()
852}
853
854pub fn gas_key_add_key_exec_fee(
858 cfg: &RuntimeFeesConfig,
859 account_id_len: usize,
860 public_key_len: usize,
861 num_nonces: NonceIndex,
862) -> GasKeyAddFee {
863 let num_nonces = num_nonces as u64;
864 let base =
865 cfg.fee(ActionCosts::gas_key_nonce_write_base).exec_fee().checked_mul(num_nonces).unwrap();
866 let nonce_key_len =
867 access_key_key_len(account_id_len, public_key_len) + std::mem::size_of::<NonceIndex>();
868 let per_byte = cfg
869 .fee(ActionCosts::gas_key_byte)
870 .exec_fee()
871 .checked_mul((nonce_key_len + AccessKey::NONCE_VALUE_LEN) as u64)
872 .unwrap()
873 .checked_mul(num_nonces)
874 .unwrap();
875 GasKeyAddFee { base, per_byte }
876}