near_parameters/
cost.rs

1use crate::parameter::Parameter;
2use enum_map::{EnumMap, enum_map};
3use near_account_id::AccountType;
4use near_primitives_core::types::{Balance, Compute, Gas};
5use near_primitives_core::version::{PROTOCOL_VERSION, ProtocolFeature};
6use near_schema_checker_lib::ProtocolSchema;
7use num_rational::Rational32;
8
9/// Costs associated with an object that can only be sent over the network (and executed
10/// by the receiver).
11/// NOTE: `send_sir` or `send_not_sir` fees are usually burned when the item is being created.
12/// And `execution` fee is burned when the item is being executed.
13#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Hash, PartialEq, Eq)]
14#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
15pub struct Fee {
16    /// Fee for sending an object from the sender to itself, guaranteeing that it does not leave
17    /// the shard.
18    pub send_sir: Gas,
19    /// Fee for sending an object potentially across the shards.
20    pub send_not_sir: Gas,
21    /// Fee for executing the object.
22    pub execution: Gas,
23}
24
25impl Fee {
26    #[inline]
27    pub fn send_fee(&self, sir: bool) -> Gas {
28        if sir { self.send_sir } else { self.send_not_sir }
29    }
30
31    pub fn exec_fee(&self) -> Gas {
32        self.execution
33    }
34
35    /// The minimum fee to send and execute.
36    pub fn min_send_and_exec_fee(&self) -> Gas {
37        std::cmp::min(self.send_sir, self.send_not_sir) + self.execution
38    }
39}
40
41#[derive(Debug, Clone, Hash, PartialEq, Eq)]
42pub struct ParameterCost {
43    pub gas: Gas,
44    pub compute: Compute,
45}
46
47#[derive(Debug, Clone, Hash, PartialEq, Eq)]
48pub struct ExtCostsConfig {
49    pub costs: EnumMap<ExtCosts, ParameterCost>,
50}
51
52// We multiply the actual computed costs by the fixed factor to ensure we
53// have certain reserve for further gas price variation.
54const SAFETY_MULTIPLIER: u64 = 3;
55
56impl ExtCostsConfig {
57    pub fn gas_cost(&self, param: ExtCosts) -> Gas {
58        self.costs[param].gas
59    }
60
61    pub fn compute_cost(&self, param: ExtCosts) -> Compute {
62        self.costs[param].compute
63    }
64
65    /// Convenience constructor to use in tests where the exact gas cost does
66    /// not need to correspond to a specific protocol version.
67    pub fn test_with_undercharging_factor(factor: u64) -> ExtCostsConfig {
68        let costs = enum_map! {
69            ExtCosts::base => SAFETY_MULTIPLIER * 88256037,
70            ExtCosts::contract_loading_base => SAFETY_MULTIPLIER * 11815321,
71            ExtCosts::contract_loading_bytes => SAFETY_MULTIPLIER * 72250,
72            ExtCosts::read_memory_base => SAFETY_MULTIPLIER * 869954400,
73            ExtCosts::read_memory_byte => SAFETY_MULTIPLIER * 1267111,
74            ExtCosts::write_memory_base => SAFETY_MULTIPLIER * 934598287,
75            ExtCosts::write_memory_byte => SAFETY_MULTIPLIER * 907924,
76            ExtCosts::read_register_base => SAFETY_MULTIPLIER * 839055062,
77            ExtCosts::read_register_byte => SAFETY_MULTIPLIER * 32854,
78            ExtCosts::write_register_base => SAFETY_MULTIPLIER * 955174162,
79            ExtCosts::write_register_byte => SAFETY_MULTIPLIER * 1267188,
80            ExtCosts::utf8_decoding_base => SAFETY_MULTIPLIER * 1037259687,
81            ExtCosts::utf8_decoding_byte => SAFETY_MULTIPLIER * 97193493,
82            ExtCosts::utf16_decoding_base => SAFETY_MULTIPLIER * 1181104350,
83            ExtCosts::utf16_decoding_byte => SAFETY_MULTIPLIER * 54525831,
84            ExtCosts::sha256_base => SAFETY_MULTIPLIER * 1513656750,
85            ExtCosts::sha256_byte => SAFETY_MULTIPLIER * 8039117,
86            ExtCosts::keccak256_base => SAFETY_MULTIPLIER * 1959830425,
87            ExtCosts::keccak256_byte => SAFETY_MULTIPLIER * 7157035,
88            ExtCosts::keccak512_base => SAFETY_MULTIPLIER * 1937129412,
89            ExtCosts::keccak512_byte => SAFETY_MULTIPLIER * 12216567,
90            ExtCosts::ripemd160_base => SAFETY_MULTIPLIER * 284558362,
91            ExtCosts::ed25519_verify_base => SAFETY_MULTIPLIER * 1513656750,
92            ExtCosts::ed25519_verify_byte => SAFETY_MULTIPLIER * 7157035,
93            ExtCosts::ripemd160_block => SAFETY_MULTIPLIER * 226702528,
94            ExtCosts::ecrecover_base => SAFETY_MULTIPLIER * 1121789875000,
95            ExtCosts::log_base => SAFETY_MULTIPLIER * 1181104350,
96            ExtCosts::log_byte => SAFETY_MULTIPLIER * 4399597,
97            ExtCosts::storage_write_base => SAFETY_MULTIPLIER * 21398912000,
98            ExtCosts::storage_write_key_byte => SAFETY_MULTIPLIER * 23494289,
99            ExtCosts::storage_write_value_byte => SAFETY_MULTIPLIER * 10339513,
100            ExtCosts::storage_write_evicted_byte => SAFETY_MULTIPLIER * 10705769,
101            ExtCosts::storage_read_base => SAFETY_MULTIPLIER * 18785615250,
102            ExtCosts::storage_read_key_byte => SAFETY_MULTIPLIER * 10317511,
103            ExtCosts::storage_read_value_byte => SAFETY_MULTIPLIER * 1870335,
104            ExtCosts::storage_large_read_overhead_base => 0,
105            ExtCosts::storage_large_read_overhead_byte => 0,
106            ExtCosts::storage_remove_base => SAFETY_MULTIPLIER * 17824343500,
107            ExtCosts::storage_remove_key_byte => SAFETY_MULTIPLIER * 12740128,
108            ExtCosts::storage_remove_ret_value_byte => SAFETY_MULTIPLIER * 3843852,
109            ExtCosts::storage_has_key_base => SAFETY_MULTIPLIER * 18013298875,
110            ExtCosts::storage_has_key_byte => SAFETY_MULTIPLIER * 10263615,
111            // Here it should be `SAFETY_MULTIPLIER * 0` for consistency, but then
112            // clippy complains with "this operation will always return zero" warning
113            ExtCosts::storage_iter_create_prefix_base => 0,
114            ExtCosts::storage_iter_create_prefix_byte => 0,
115            ExtCosts::storage_iter_create_range_base => 0,
116            ExtCosts::storage_iter_create_from_byte => 0,
117            ExtCosts::storage_iter_create_to_byte => 0,
118            ExtCosts::storage_iter_next_base => 0,
119            ExtCosts::storage_iter_next_key_byte => 0,
120            ExtCosts::storage_iter_next_value_byte => 0,
121            ExtCosts::touching_trie_node => SAFETY_MULTIPLIER * 5367318642,
122            ExtCosts::read_cached_trie_node => SAFETY_MULTIPLIER * 760_000_000,
123            ExtCosts::promise_and_base => SAFETY_MULTIPLIER * 488337800,
124            ExtCosts::promise_and_per_promise => SAFETY_MULTIPLIER * 1817392,
125            ExtCosts::promise_return => SAFETY_MULTIPLIER * 186717462,
126            ExtCosts::validator_stake_base => SAFETY_MULTIPLIER * 303944908800,
127            ExtCosts::validator_total_stake_base => SAFETY_MULTIPLIER * 303944908800,
128            ExtCosts::alt_bn128_g1_multiexp_base => 713_000_000_000,
129            ExtCosts::alt_bn128_g1_multiexp_element => 320_000_000_000,
130            ExtCosts::alt_bn128_pairing_check_base => 9_686_000_000_000,
131            ExtCosts::alt_bn128_pairing_check_element => 5_102_000_000_000,
132            ExtCosts::alt_bn128_g1_sum_base => 3_000_000_000,
133            ExtCosts::alt_bn128_g1_sum_element => 5_000_000_000,
134            ExtCosts::bls12381_p1_sum_base => SAFETY_MULTIPLIER * 5_500_000_000,
135            ExtCosts::bls12381_p1_sum_element => SAFETY_MULTIPLIER * 2_000_000_000,
136            ExtCosts::bls12381_p2_sum_base => SAFETY_MULTIPLIER * 6_200_000_000,
137            ExtCosts::bls12381_p2_sum_element => SAFETY_MULTIPLIER * 5_000_000_000,
138            ExtCosts::bls12381_g1_multiexp_base => SAFETY_MULTIPLIER * 5_500_000_000,
139            ExtCosts::bls12381_g1_multiexp_element => SAFETY_MULTIPLIER * 310_000_000_000,
140            ExtCosts::bls12381_g2_multiexp_base => SAFETY_MULTIPLIER * 6_200_000_000,
141            ExtCosts::bls12381_g2_multiexp_element => SAFETY_MULTIPLIER * 665_000_000_000,
142            ExtCosts::bls12381_map_fp_to_g1_base => SAFETY_MULTIPLIER * 500_000_000,
143            ExtCosts::bls12381_map_fp_to_g1_element => SAFETY_MULTIPLIER * 84_000_000_000,
144            ExtCosts::bls12381_map_fp2_to_g2_base => SAFETY_MULTIPLIER * 500_000_000,
145            ExtCosts::bls12381_map_fp2_to_g2_element => SAFETY_MULTIPLIER * 300_000_000_000,
146            ExtCosts::bls12381_pairing_base => SAFETY_MULTIPLIER * 710_000_000_000,
147            ExtCosts::bls12381_pairing_element => SAFETY_MULTIPLIER * 710_000_000_000,
148            ExtCosts::bls12381_p1_decompress_base => SAFETY_MULTIPLIER * 500_000_000,
149            ExtCosts::bls12381_p1_decompress_element => SAFETY_MULTIPLIER * 27_000_000_000,
150            ExtCosts::bls12381_p2_decompress_base => SAFETY_MULTIPLIER * 500_000_000,
151            ExtCosts::bls12381_p2_decompress_element => SAFETY_MULTIPLIER * 55_000_000_000,
152            // TODO(yield/resume): replicate fees here after estimation
153            ExtCosts::yield_create_base => 300_000_000_000_000,
154            ExtCosts::yield_create_byte => 300_000_000_000_000,
155            ExtCosts::yield_resume_base => 300_000_000_000_000,
156            ExtCosts::yield_resume_byte => 300_000_000_000_000,
157        }
158        .map(|_, value| ParameterCost { gas: value, compute: value * factor });
159        ExtCostsConfig { costs }
160    }
161
162    /// `test_with_undercharging_factor` with a factor of 1.
163    pub fn test() -> ExtCostsConfig {
164        Self::test_with_undercharging_factor(1)
165    }
166}
167
168/// Strongly-typed representation of the fees for counting.
169///
170/// Do not change the enum discriminants here, they are used for borsh
171/// (de-)serialization.
172#[derive(
173    Copy,
174    Clone,
175    Hash,
176    PartialEq,
177    Eq,
178    Debug,
179    PartialOrd,
180    Ord,
181    strum::Display,
182    strum::EnumIter,
183    enum_map::Enum,
184    ProtocolSchema,
185)]
186#[allow(non_camel_case_types)]
187pub enum ExtCosts {
188    base = 0,
189    contract_loading_base = 1,
190    contract_loading_bytes = 2,
191    read_memory_base = 3,
192    read_memory_byte = 4,
193    write_memory_base = 5,
194    write_memory_byte = 6,
195    read_register_base = 7,
196    read_register_byte = 8,
197    write_register_base = 9,
198    write_register_byte = 10,
199    utf8_decoding_base = 11,
200    utf8_decoding_byte = 12,
201    utf16_decoding_base = 13,
202    utf16_decoding_byte = 14,
203    sha256_base = 15,
204    sha256_byte = 16,
205    keccak256_base = 17,
206    keccak256_byte = 18,
207    keccak512_base = 19,
208    keccak512_byte = 20,
209    ripemd160_base = 21,
210    ripemd160_block = 22,
211    ecrecover_base = 23,
212    log_base = 24,
213    log_byte = 25,
214    storage_write_base = 26,
215    storage_write_key_byte = 27,
216    storage_write_value_byte = 28,
217    storage_write_evicted_byte = 29,
218    storage_read_base = 30,
219    storage_read_key_byte = 31,
220    storage_read_value_byte = 32,
221    storage_remove_base = 33,
222    storage_remove_key_byte = 34,
223    storage_remove_ret_value_byte = 35,
224    storage_has_key_base = 36,
225    storage_has_key_byte = 37,
226    storage_iter_create_prefix_base = 38,
227    storage_iter_create_prefix_byte = 39,
228    storage_iter_create_range_base = 40,
229    storage_iter_create_from_byte = 41,
230    storage_iter_create_to_byte = 42,
231    storage_iter_next_base = 43,
232    storage_iter_next_key_byte = 44,
233    storage_iter_next_value_byte = 45,
234    touching_trie_node = 46,
235    read_cached_trie_node = 47,
236    promise_and_base = 48,
237    promise_and_per_promise = 49,
238    promise_return = 50,
239    validator_stake_base = 51,
240    validator_total_stake_base = 52,
241    alt_bn128_g1_multiexp_base = 53,
242    alt_bn128_g1_multiexp_element = 54,
243    alt_bn128_pairing_check_base = 55,
244    alt_bn128_pairing_check_element = 56,
245    alt_bn128_g1_sum_base = 57,
246    alt_bn128_g1_sum_element = 58,
247    ed25519_verify_base = 59,
248    ed25519_verify_byte = 60,
249    yield_create_base = 61,
250    yield_create_byte = 62,
251    yield_resume_base = 63,
252    yield_resume_byte = 64,
253    bls12381_p1_sum_base = 65,
254    bls12381_p1_sum_element = 66,
255    bls12381_p2_sum_base = 67,
256    bls12381_p2_sum_element = 68,
257    bls12381_g1_multiexp_base = 69,
258    bls12381_g1_multiexp_element = 70,
259    bls12381_g2_multiexp_base = 71,
260    bls12381_g2_multiexp_element = 72,
261    bls12381_map_fp_to_g1_base = 73,
262    bls12381_map_fp_to_g1_element = 74,
263    bls12381_map_fp2_to_g2_base = 75,
264    bls12381_map_fp2_to_g2_element = 76,
265    bls12381_pairing_base = 77,
266    bls12381_pairing_element = 78,
267    bls12381_p1_decompress_base = 79,
268    bls12381_p1_decompress_element = 80,
269    bls12381_p2_decompress_base = 81,
270    bls12381_p2_decompress_element = 82,
271    storage_large_read_overhead_base = 83,
272    storage_large_read_overhead_byte = 84,
273}
274
275// Type of an action, used in fees logic.
276#[derive(
277    Copy,
278    Clone,
279    Hash,
280    PartialEq,
281    Eq,
282    Debug,
283    PartialOrd,
284    Ord,
285    strum::Display,
286    strum::EnumIter,
287    enum_map::Enum,
288    ProtocolSchema,
289)]
290#[allow(non_camel_case_types)]
291pub enum ActionCosts {
292    create_account = 0,
293    delete_account = 1,
294    deploy_contract_base = 2,
295    deploy_contract_byte = 3,
296    function_call_base = 4,
297    function_call_byte = 5,
298    transfer = 6,
299    stake = 7,
300    add_full_access_key = 8,
301    add_function_call_key_base = 9,
302    add_function_call_key_byte = 10,
303    delete_key = 11,
304    new_action_receipt = 12,
305    new_data_receipt_base = 13,
306    new_data_receipt_byte = 14,
307    delegate = 15,
308    deploy_global_contract_base = 16,
309    deploy_global_contract_byte = 17,
310    use_global_contract_base = 18,
311    use_global_contract_byte = 19,
312}
313
314impl ExtCosts {
315    pub fn gas(self, config: &ExtCostsConfig) -> Gas {
316        config.gas_cost(self)
317    }
318
319    pub fn compute(self, config: &ExtCostsConfig) -> Compute {
320        config.compute_cost(self)
321    }
322
323    pub fn param(&self) -> Parameter {
324        match self {
325            ExtCosts::base => Parameter::WasmBase,
326            ExtCosts::contract_loading_base => Parameter::WasmContractLoadingBase,
327            ExtCosts::contract_loading_bytes => Parameter::WasmContractLoadingBytes,
328            ExtCosts::read_memory_base => Parameter::WasmReadMemoryBase,
329            ExtCosts::read_memory_byte => Parameter::WasmReadMemoryByte,
330            ExtCosts::write_memory_base => Parameter::WasmWriteMemoryBase,
331            ExtCosts::write_memory_byte => Parameter::WasmWriteMemoryByte,
332            ExtCosts::read_register_base => Parameter::WasmReadRegisterBase,
333            ExtCosts::read_register_byte => Parameter::WasmReadRegisterByte,
334            ExtCosts::write_register_base => Parameter::WasmWriteRegisterBase,
335            ExtCosts::write_register_byte => Parameter::WasmWriteRegisterByte,
336            ExtCosts::utf8_decoding_base => Parameter::WasmUtf8DecodingBase,
337            ExtCosts::utf8_decoding_byte => Parameter::WasmUtf8DecodingByte,
338            ExtCosts::utf16_decoding_base => Parameter::WasmUtf16DecodingBase,
339            ExtCosts::utf16_decoding_byte => Parameter::WasmUtf16DecodingByte,
340            ExtCosts::sha256_base => Parameter::WasmSha256Base,
341            ExtCosts::sha256_byte => Parameter::WasmSha256Byte,
342            ExtCosts::keccak256_base => Parameter::WasmKeccak256Base,
343            ExtCosts::keccak256_byte => Parameter::WasmKeccak256Byte,
344            ExtCosts::keccak512_base => Parameter::WasmKeccak512Base,
345            ExtCosts::keccak512_byte => Parameter::WasmKeccak512Byte,
346            ExtCosts::ripemd160_base => Parameter::WasmRipemd160Base,
347            ExtCosts::ripemd160_block => Parameter::WasmRipemd160Block,
348            ExtCosts::ecrecover_base => Parameter::WasmEcrecoverBase,
349            ExtCosts::ed25519_verify_base => Parameter::WasmEd25519VerifyBase,
350            ExtCosts::ed25519_verify_byte => Parameter::WasmEd25519VerifyByte,
351            ExtCosts::log_base => Parameter::WasmLogBase,
352            ExtCosts::log_byte => Parameter::WasmLogByte,
353            ExtCosts::storage_write_base => Parameter::WasmStorageWriteBase,
354            ExtCosts::storage_write_key_byte => Parameter::WasmStorageWriteKeyByte,
355            ExtCosts::storage_write_value_byte => Parameter::WasmStorageWriteValueByte,
356            ExtCosts::storage_write_evicted_byte => Parameter::WasmStorageWriteEvictedByte,
357            ExtCosts::storage_read_base => Parameter::WasmStorageReadBase,
358            ExtCosts::storage_read_key_byte => Parameter::WasmStorageReadKeyByte,
359            ExtCosts::storage_read_value_byte => Parameter::WasmStorageReadValueByte,
360            ExtCosts::storage_large_read_overhead_base => {
361                Parameter::WasmStorageLargeReadOverheadBase
362            }
363            ExtCosts::storage_large_read_overhead_byte => {
364                Parameter::WasmStorageLargeReadOverheadByte
365            }
366            ExtCosts::storage_remove_base => Parameter::WasmStorageRemoveBase,
367            ExtCosts::storage_remove_key_byte => Parameter::WasmStorageRemoveKeyByte,
368            ExtCosts::storage_remove_ret_value_byte => Parameter::WasmStorageRemoveRetValueByte,
369            ExtCosts::storage_has_key_base => Parameter::WasmStorageHasKeyBase,
370            ExtCosts::storage_has_key_byte => Parameter::WasmStorageHasKeyByte,
371            ExtCosts::storage_iter_create_prefix_base => Parameter::WasmStorageIterCreatePrefixBase,
372            ExtCosts::storage_iter_create_prefix_byte => Parameter::WasmStorageIterCreatePrefixByte,
373            ExtCosts::storage_iter_create_range_base => Parameter::WasmStorageIterCreateRangeBase,
374            ExtCosts::storage_iter_create_from_byte => Parameter::WasmStorageIterCreateFromByte,
375            ExtCosts::storage_iter_create_to_byte => Parameter::WasmStorageIterCreateToByte,
376            ExtCosts::storage_iter_next_base => Parameter::WasmStorageIterNextBase,
377            ExtCosts::storage_iter_next_key_byte => Parameter::WasmStorageIterNextKeyByte,
378            ExtCosts::storage_iter_next_value_byte => Parameter::WasmStorageIterNextValueByte,
379            ExtCosts::touching_trie_node => Parameter::WasmTouchingTrieNode,
380            ExtCosts::read_cached_trie_node => Parameter::WasmReadCachedTrieNode,
381            ExtCosts::promise_and_base => Parameter::WasmPromiseAndBase,
382            ExtCosts::promise_and_per_promise => Parameter::WasmPromiseAndPerPromise,
383            ExtCosts::promise_return => Parameter::WasmPromiseReturn,
384            ExtCosts::validator_stake_base => Parameter::WasmValidatorStakeBase,
385            ExtCosts::validator_total_stake_base => Parameter::WasmValidatorTotalStakeBase,
386            ExtCosts::alt_bn128_g1_multiexp_base => Parameter::WasmAltBn128G1MultiexpBase,
387            ExtCosts::alt_bn128_g1_multiexp_element => Parameter::WasmAltBn128G1MultiexpElement,
388            ExtCosts::alt_bn128_pairing_check_base => Parameter::WasmAltBn128PairingCheckBase,
389            ExtCosts::alt_bn128_pairing_check_element => Parameter::WasmAltBn128PairingCheckElement,
390            ExtCosts::alt_bn128_g1_sum_base => Parameter::WasmAltBn128G1SumBase,
391            ExtCosts::alt_bn128_g1_sum_element => Parameter::WasmAltBn128G1SumElement,
392            ExtCosts::yield_create_base => Parameter::WasmYieldCreateBase,
393            ExtCosts::yield_create_byte => Parameter::WasmYieldCreateByte,
394            ExtCosts::yield_resume_base => Parameter::WasmYieldResumeBase,
395            ExtCosts::yield_resume_byte => Parameter::WasmYieldResumeByte,
396            ExtCosts::bls12381_p1_sum_base => Parameter::WasmBls12381P1SumBase,
397            ExtCosts::bls12381_p1_sum_element => Parameter::WasmBls12381P1SumElement,
398            ExtCosts::bls12381_p2_sum_base => Parameter::WasmBls12381P2SumBase,
399            ExtCosts::bls12381_p2_sum_element => Parameter::WasmBls12381P2SumElement,
400            ExtCosts::bls12381_g1_multiexp_base => Parameter::WasmBls12381G1MultiexpBase,
401            ExtCosts::bls12381_g1_multiexp_element => Parameter::WasmBls12381G1MultiexpElement,
402            ExtCosts::bls12381_g2_multiexp_base => Parameter::WasmBls12381G2MultiexpBase,
403            ExtCosts::bls12381_g2_multiexp_element => Parameter::WasmBls12381G2MultiexpElement,
404            ExtCosts::bls12381_map_fp_to_g1_base => Parameter::WasmBls12381MapFpToG1Base,
405            ExtCosts::bls12381_map_fp_to_g1_element => Parameter::WasmBls12381MapFpToG1Element,
406            ExtCosts::bls12381_map_fp2_to_g2_base => Parameter::WasmBls12381MapFp2ToG2Base,
407            ExtCosts::bls12381_map_fp2_to_g2_element => Parameter::WasmBls12381MapFp2ToG2Element,
408            ExtCosts::bls12381_pairing_base => Parameter::WasmBls12381PairingBase,
409            ExtCosts::bls12381_pairing_element => Parameter::WasmBls12381PairingElement,
410            ExtCosts::bls12381_p1_decompress_base => Parameter::WasmBls12381P1DecompressBase,
411            ExtCosts::bls12381_p1_decompress_element => Parameter::WasmBls12381P1DecompressElement,
412            ExtCosts::bls12381_p2_decompress_base => Parameter::WasmBls12381P2DecompressBase,
413            ExtCosts::bls12381_p2_decompress_element => Parameter::WasmBls12381P2DecompressElement,
414        }
415    }
416}
417
418#[derive(Debug, Clone, Hash, PartialEq, Eq)]
419pub struct RuntimeFeesConfig {
420    /// Gas fees for sending and executing actions.
421    pub action_fees: EnumMap<ActionCosts, Fee>,
422
423    /// Describes fees for storage.
424    pub storage_usage_config: StorageUsageConfig,
425
426    /// Fraction of the burnt gas to reward to the contract account for execution.
427    pub burnt_gas_reward: Rational32,
428
429    /// Pessimistic gas price inflation ratio.
430    pub pessimistic_gas_price_inflation_ratio: Rational32,
431
432    /// Whether we calculate in the gas price changes when refunding gas.
433    ///
434    /// Changed to false with [NEP-536](https://github.com/near/NEPs/pull/536)
435    pub refund_gas_price_changes: bool,
436
437    /// Relative cost for gas refunds as a ratio of the refunded amount.
438    ///
439    /// The actual penalty is
440    /// `max(gross_refund * gas_refund_penalty, min_gas_refund_penalty)`
441    ///
442    /// Added with [NEP-536](https://github.com/near/NEPs/pull/536)
443    pub gas_refund_penalty: Rational32,
444    /// Minimum cost for gas refunds.
445    ///
446    /// The actual penalty is
447    /// `max(gross_refund * gas_refund_penalty, min_gas_refund_penalty)`
448    ///
449    /// Added with [NEP-536](https://github.com/near/NEPs/pull/536)
450    pub min_gas_refund_penalty: Gas,
451}
452
453/// Describes cost of storage per block
454#[derive(Debug, Clone, Hash, PartialEq, Eq)]
455pub struct StorageUsageConfig {
456    /// Amount of yN per byte required to have on the account. See
457    /// <https://nomicon.io/Economics/README.html#state-stake> for details.
458    pub storage_amount_per_byte: Balance,
459    /// Number of bytes for an account record, including rounding up for account id.
460    pub num_bytes_account: u64,
461    /// Additional number of bytes for a k/v record
462    pub num_extra_bytes_record: u64,
463    /// Amount of yN burned per byte of deployed Global Contract code.
464    pub global_contract_storage_amount_per_byte: Balance,
465}
466
467impl RuntimeFeesConfig {
468    /// Access action fee by `ActionCosts`.
469    pub fn fee(&self, cost: ActionCosts) -> &Fee {
470        &self.action_fees[cost]
471    }
472
473    pub fn test() -> Self {
474        Self {
475            storage_usage_config: StorageUsageConfig::test(),
476            burnt_gas_reward: Rational32::new(3, 10),
477            pessimistic_gas_price_inflation_ratio: Rational32::new(103, 100),
478            refund_gas_price_changes: !ProtocolFeature::ReducedGasRefunds.enabled(PROTOCOL_VERSION),
479            gas_refund_penalty: if ProtocolFeature::ReducedGasRefunds.enabled(PROTOCOL_VERSION) {
480                Rational32::new(5, 100)
481            } else {
482                Rational32::new(0, 100)
483            },
484            min_gas_refund_penalty: if ProtocolFeature::ReducedGasRefunds.enabled(PROTOCOL_VERSION)
485            {
486                1_000_000_000_000
487            } else {
488                0
489            },
490            action_fees: enum_map::enum_map! {
491                ActionCosts::create_account => Fee {
492                    send_sir: 3_850_000_000_000,
493                    send_not_sir: 3_850_000_000_000,
494                    execution: 3_850_000_000_000,
495                },
496                ActionCosts::delete_account => Fee {
497                    send_sir: 147489000000,
498                    send_not_sir: 147489000000,
499                    execution: 147489000000,
500                },
501                ActionCosts::deploy_contract_base => Fee {
502                    send_sir: 184765750000,
503                    send_not_sir: 184765750000,
504                    execution: 184765750000,
505                },
506                ActionCosts::deploy_contract_byte => Fee {
507                    send_sir: 6812999,
508                    send_not_sir: 6812999,
509                    execution: 6812999,
510                },
511                ActionCosts::function_call_base => Fee {
512                    send_sir: 2319861500000,
513                    send_not_sir: 2319861500000,
514                    execution: 2319861500000,
515                },
516                ActionCosts::function_call_byte => Fee {
517                    send_sir: 2235934,
518                    send_not_sir: 2235934,
519                    execution: 2235934,
520                },
521                ActionCosts::transfer => Fee {
522                    send_sir: 115123062500,
523                    send_not_sir: 115123062500,
524                    execution: 115123062500,
525                },
526                ActionCosts::stake => Fee {
527                    send_sir: 141715687500,
528                    send_not_sir: 141715687500,
529                    execution: 102217625000,
530                },
531                ActionCosts::add_full_access_key => Fee {
532                    send_sir: 101765125000,
533                    send_not_sir: 101765125000,
534                    execution: 101765125000,
535                },
536                ActionCosts::add_function_call_key_base => Fee {
537                    send_sir: 102217625000,
538                    send_not_sir: 102217625000,
539                    execution: 102217625000,
540                },
541                ActionCosts::add_function_call_key_byte => Fee {
542                    send_sir: 1925331,
543                    send_not_sir: 1925331,
544                    execution: 1925331,
545                },
546                ActionCosts::delete_key => Fee {
547                    send_sir: 94946625000,
548                    send_not_sir: 94946625000,
549                    execution: 94946625000,
550                },
551                ActionCosts::new_action_receipt => Fee {
552                    send_sir: 108059500000,
553                    send_not_sir: 108059500000,
554                    execution: 108059500000,
555                },
556                ActionCosts::new_data_receipt_base => Fee {
557                    send_sir: 4697339419375,
558                    send_not_sir: 4697339419375,
559                    execution: 4697339419375,
560                },
561                ActionCosts::new_data_receipt_byte => Fee {
562                    send_sir: 59357464,
563                    send_not_sir: 59357464,
564                    execution: 59357464,
565                },
566                ActionCosts::delegate => Fee {
567                    send_sir: 200_000_000_000,
568                    send_not_sir: 200_000_000_000,
569                    execution: 200_000_000_000,
570                },
571                ActionCosts::deploy_global_contract_base => Fee {
572                    send_sir: 184_765_750_000,
573                    send_not_sir: 184_765_750_000,
574                    execution: 184_765_750_000,
575                },
576                ActionCosts::deploy_global_contract_byte => Fee {
577                    send_sir: 6_812_999,
578                    send_not_sir: 6_812_999,
579                    execution: 70_000_000,
580                },
581                ActionCosts::use_global_contract_base => Fee {
582                    send_sir: 184_765_750_000,
583                    send_not_sir: 184_765_750_000,
584                    execution: 184_765_750_000,
585                },
586                ActionCosts::use_global_contract_byte => Fee {
587                    send_sir: 6_812_999,
588                    send_not_sir: 47_683_715,
589                    execution: 64_572_944,
590                },
591            },
592        }
593    }
594
595    pub fn free() -> Self {
596        Self {
597            action_fees: enum_map::enum_map! {
598                _ => Fee { send_sir: 0, send_not_sir: 0, execution: 0 }
599            },
600            storage_usage_config: StorageUsageConfig::free(),
601            burnt_gas_reward: Rational32::from_integer(0),
602            pessimistic_gas_price_inflation_ratio: Rational32::from_integer(0),
603            refund_gas_price_changes: !ProtocolFeature::ReducedGasRefunds.enabled(PROTOCOL_VERSION),
604            gas_refund_penalty: Rational32::from_integer(0),
605            min_gas_refund_penalty: 0,
606        }
607    }
608
609    /// The minimum amount of gas required to create and execute a new receipt with a function call
610    /// action.
611    /// This amount is used to determine how many receipts can be created, send and executed for
612    /// some amount of prepaid gas using function calls.
613    pub fn min_receipt_with_function_call_gas(&self) -> Gas {
614        self.fee(ActionCosts::new_action_receipt).min_send_and_exec_fee()
615            + self.fee(ActionCosts::function_call_base).min_send_and_exec_fee()
616    }
617
618    /// Given a left over gas amount to be refunded, returns how much should be
619    /// subtracted as a penalty introduced with NEP-536.
620    ///
621    /// Must return a value smaller or equal to the `gas_refund` parameter.
622    pub fn gas_penalty_for_gas_refund(&self, gas_refund: Gas) -> Gas {
623        let relative_cost = (gas_refund as u128 * *self.gas_refund_penalty.numer() as u128
624            / *self.gas_refund_penalty.denom() as u128) as Gas;
625
626        let penalty = std::cmp::max(relative_cost, self.min_gas_refund_penalty);
627        std::cmp::min(penalty, gas_refund)
628    }
629}
630
631impl StorageUsageConfig {
632    pub fn test() -> Self {
633        Self {
634            num_bytes_account: 100,
635            num_extra_bytes_record: 40,
636            storage_amount_per_byte: 909 * 100_000_000_000_000_000,
637            global_contract_storage_amount_per_byte: 100_000_000_000_000_000_000,
638        }
639    }
640
641    pub(crate) fn free() -> StorageUsageConfig {
642        Self {
643            num_bytes_account: 0,
644            num_extra_bytes_record: 0,
645            storage_amount_per_byte: 0,
646            global_contract_storage_amount_per_byte: 0,
647        }
648    }
649}
650
651/// Helper functions for computing Transfer fees.
652/// In case of implicit account creation they include extra fees for the CreateAccount and
653/// AddFullAccessKey (for NEAR-implicit account only) actions that are implicit.
654/// We can assume that no overflow will happen here.
655pub fn transfer_exec_fee(
656    cfg: &RuntimeFeesConfig,
657    implicit_account_creation_allowed: bool,
658    eth_implicit_accounts_enabled: bool,
659    receiver_account_type: AccountType,
660) -> Gas {
661    let transfer_fee = cfg.fee(ActionCosts::transfer).exec_fee();
662    match (implicit_account_creation_allowed, eth_implicit_accounts_enabled, receiver_account_type)
663    {
664        // Regular transfer to a named account.
665        (_, _, AccountType::NamedAccount) => transfer_fee,
666        // No account will be created, just a regular transfer.
667        (false, _, _) => transfer_fee,
668        // No account will be created, just a regular transfer.
669        (true, false, AccountType::EthImplicitAccount) => transfer_fee,
670        // Extra fee for the CreateAccount.
671        (true, true, AccountType::EthImplicitAccount) => {
672            transfer_fee + cfg.fee(ActionCosts::create_account).exec_fee()
673        }
674        // Extra fees for the CreateAccount and AddFullAccessKey.
675        (true, _, AccountType::NearImplicitAccount) => {
676            transfer_fee
677                + cfg.fee(ActionCosts::create_account).exec_fee()
678                + cfg.fee(ActionCosts::add_full_access_key).exec_fee()
679        }
680    }
681}
682
683pub fn transfer_send_fee(
684    cfg: &RuntimeFeesConfig,
685    sender_is_receiver: bool,
686    implicit_account_creation_allowed: bool,
687    eth_implicit_accounts_enabled: bool,
688    receiver_account_type: AccountType,
689) -> Gas {
690    let transfer_fee = cfg.fee(ActionCosts::transfer).send_fee(sender_is_receiver);
691    match (implicit_account_creation_allowed, eth_implicit_accounts_enabled, receiver_account_type)
692    {
693        // Regular transfer to a named account.
694        (_, _, AccountType::NamedAccount) => transfer_fee,
695        // No account will be created, just a regular transfer.
696        (false, _, _) => transfer_fee,
697        // No account will be created, just a regular transfer.
698        (true, false, AccountType::EthImplicitAccount) => transfer_fee,
699        // Extra fee for the CreateAccount.
700        (true, true, AccountType::EthImplicitAccount) => {
701            transfer_fee + cfg.fee(ActionCosts::create_account).send_fee(sender_is_receiver)
702        }
703        // Extra fees for the CreateAccount and AddFullAccessKey.
704        (true, _, AccountType::NearImplicitAccount) => {
705            transfer_fee
706                + cfg.fee(ActionCosts::create_account).send_fee(sender_is_receiver)
707                + cfg.fee(ActionCosts::add_full_access_key).send_fee(sender_is_receiver)
708        }
709    }
710}