unc_parameters/
cost.rs

1use crate::parameter::Parameter;
2use enum_map::{enum_map, EnumMap};
3use num_rational::Rational32;
4use unc_account_id::AccountType;
5use unc_primitives_core::types::{Balance, Compute, Gas};
6
7/// Costs associated with an object that can only be sent over the network (and executed
8/// by the receiver).
9/// NOTE: `send_sir` or `send_not_sir` fees are usually burned when the item is being created.
10/// And `execution` fee is burned when the item is being executed.
11#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Hash, PartialEq, Eq)]
12pub struct Fee {
13    /// Fee for sending an object from the sender to itself, guaranteeing that it does not leave
14    /// the shard.
15    pub send_sir: Gas,
16    /// Fee for sending an object potentially across the shards.
17    pub send_not_sir: Gas,
18    /// Fee for executing the object.
19    pub execution: Gas,
20}
21
22impl Fee {
23    #[inline]
24    pub fn send_fee(&self, sir: bool) -> Gas {
25        if sir {
26            self.send_sir
27        } else {
28            self.send_not_sir
29        }
30    }
31
32    pub fn exec_fee(&self) -> Gas {
33        self.execution
34    }
35
36    /// The minimum fee to send and execute.
37    pub fn min_send_and_exec_fee(&self) -> Gas {
38        std::cmp::min(self.send_sir, self.send_not_sir) + self.execution
39    }
40}
41
42#[derive(Debug, Clone, Hash, PartialEq, Eq)]
43pub struct ParameterCost {
44    pub gas: Gas,
45    pub compute: Compute,
46}
47
48#[derive(Debug, Clone, Hash, PartialEq, Eq)]
49pub struct ExtCostsConfig {
50    pub costs: EnumMap<ExtCosts, ParameterCost>,
51}
52
53// We multiply the actual computed costs by the fixed factor to ensure we
54// have certain reserve for further gas price variation.
55const SAFETY_MULTIPLIER: u64 = 3;
56
57impl ExtCostsConfig {
58    pub fn gas_cost(&self, param: ExtCosts) -> Gas {
59        self.costs[param].gas
60    }
61
62    pub fn compute_cost(&self, param: ExtCosts) -> Compute {
63        self.costs[param].compute
64    }
65
66    /// Convenience constructor to use in tests where the exact gas cost does
67    /// not need to correspond to a specific protocol version.
68    pub fn test_with_undercharging_factor(factor: u64) -> ExtCostsConfig {
69        let costs = enum_map! {
70            ExtCosts::base => SAFETY_MULTIPLIER * 88256037,
71            ExtCosts::contract_loading_base => SAFETY_MULTIPLIER * 11815321,
72            ExtCosts::contract_loading_bytes => SAFETY_MULTIPLIER * 72250,
73            ExtCosts::read_memory_base => SAFETY_MULTIPLIER * 869954400,
74            ExtCosts::read_memory_byte => SAFETY_MULTIPLIER * 1267111,
75            ExtCosts::write_memory_base => SAFETY_MULTIPLIER * 934598287,
76            ExtCosts::write_memory_byte => SAFETY_MULTIPLIER * 907924,
77            ExtCosts::read_register_base => SAFETY_MULTIPLIER * 839055062,
78            ExtCosts::read_register_byte => SAFETY_MULTIPLIER * 32854,
79            ExtCosts::write_register_base => SAFETY_MULTIPLIER * 955174162,
80            ExtCosts::write_register_byte => SAFETY_MULTIPLIER * 1267188,
81            ExtCosts::utf8_decoding_base => SAFETY_MULTIPLIER * 1037259687,
82            ExtCosts::utf8_decoding_byte => SAFETY_MULTIPLIER * 97193493,
83            ExtCosts::utf16_decoding_base => SAFETY_MULTIPLIER * 1181104350,
84            ExtCosts::utf16_decoding_byte => SAFETY_MULTIPLIER * 54525831,
85            ExtCosts::sha256_base => SAFETY_MULTIPLIER * 1513656750,
86            ExtCosts::sha256_byte => SAFETY_MULTIPLIER * 8039117,
87            ExtCosts::keccak256_base => SAFETY_MULTIPLIER * 1959830425,
88            ExtCosts::keccak256_byte => SAFETY_MULTIPLIER * 7157035,
89            ExtCosts::keccak512_base => SAFETY_MULTIPLIER * 1937129412,
90            ExtCosts::keccak512_byte => SAFETY_MULTIPLIER * 12216567,
91            ExtCosts::ripemd160_base => SAFETY_MULTIPLIER * 284558362,
92            ExtCosts::ed25519_verify_base => SAFETY_MULTIPLIER * 1513656750,
93            ExtCosts::ed25519_verify_byte => SAFETY_MULTIPLIER * 7157035,
94            ExtCosts::ripemd160_block => SAFETY_MULTIPLIER * 226702528,
95            ExtCosts::ecrecover_base => SAFETY_MULTIPLIER * 1121789875000,
96            ExtCosts::log_base => SAFETY_MULTIPLIER * 1181104350,
97            ExtCosts::log_byte => SAFETY_MULTIPLIER * 4399597,
98            ExtCosts::storage_write_base => SAFETY_MULTIPLIER * 21398912000,
99            ExtCosts::storage_write_key_byte => SAFETY_MULTIPLIER * 23494289,
100            ExtCosts::storage_write_value_byte => SAFETY_MULTIPLIER * 10339513,
101            ExtCosts::storage_write_evicted_byte => SAFETY_MULTIPLIER * 10705769,
102            ExtCosts::storage_read_base => SAFETY_MULTIPLIER * 18785615250,
103            ExtCosts::storage_read_key_byte => SAFETY_MULTIPLIER * 10317511,
104            ExtCosts::storage_read_value_byte => SAFETY_MULTIPLIER * 1870335,
105            ExtCosts::storage_remove_base => SAFETY_MULTIPLIER * 17824343500,
106            ExtCosts::storage_remove_key_byte => SAFETY_MULTIPLIER * 12740128,
107            ExtCosts::storage_remove_ret_value_byte => SAFETY_MULTIPLIER * 3843852,
108            ExtCosts::storage_has_key_base => SAFETY_MULTIPLIER * 18013298875,
109            ExtCosts::storage_has_key_byte => SAFETY_MULTIPLIER * 10263615,
110            // Here it should be `SAFETY_MULTIPLIER * 0` for consistency, but then
111            // clippy complains with "this operation will always return zero" warning
112            ExtCosts::storage_iter_create_prefix_base => 0,
113            ExtCosts::storage_iter_create_prefix_byte => 0,
114            ExtCosts::storage_iter_create_range_base => 0,
115            ExtCosts::storage_iter_create_from_byte => 0,
116            ExtCosts::storage_iter_create_to_byte => 0,
117            ExtCosts::storage_iter_next_base => 0,
118            ExtCosts::storage_iter_next_key_byte => 0,
119            ExtCosts::storage_iter_next_value_byte => 0,
120            ExtCosts::touching_trie_node => SAFETY_MULTIPLIER * 5367318642,
121            ExtCosts::read_cached_trie_node => SAFETY_MULTIPLIER * 760_000_000,
122            ExtCosts::promise_and_base => SAFETY_MULTIPLIER * 488337800,
123            ExtCosts::promise_and_per_promise => SAFETY_MULTIPLIER * 1817392,
124            ExtCosts::promise_return => SAFETY_MULTIPLIER * 186717462,
125            ExtCosts::validator_pledge_base => SAFETY_MULTIPLIER * 303944908800,
126            ExtCosts::validator_total_pledge_base => SAFETY_MULTIPLIER * 303944908800,
127            ExtCosts::alt_bn128_g1_multiexp_base => 713_000_000_000,
128            ExtCosts::alt_bn128_g1_multiexp_element => 320_000_000_000,
129            ExtCosts::alt_bn128_pairing_check_base => 9_686_000_000_000,
130            ExtCosts::alt_bn128_pairing_check_element => 5_102_000_000_000,
131            ExtCosts::alt_bn128_g1_sum_base => 3_000_000_000,
132            ExtCosts::alt_bn128_g1_sum_element => 5_000_000_000,
133            ExtCosts::validator_power_base => SAFETY_MULTIPLIER * 3_000_000_000,
134            ExtCosts::validator_total_power_base => SAFETY_MULTIPLIER * 3_000_000_000,
135        }
136        .map(|_, value| ParameterCost { gas: value, compute: value * factor });
137        ExtCostsConfig { costs }
138    }
139
140    /// `test_with_undercharging_factor` with a factor of 1.
141    pub fn test() -> ExtCostsConfig {
142        Self::test_with_undercharging_factor(1)
143    }
144}
145
146/// Strongly-typed representation of the fees for counting.
147///
148/// Do not change the enum discriminants here, they are used for borsh
149/// (de-)serialization.
150#[derive(
151    Copy,
152    Clone,
153    Hash,
154    PartialEq,
155    Eq,
156    Debug,
157    PartialOrd,
158    Ord,
159    strum::Display,
160    strum::EnumIter,
161    enum_map::Enum,
162)]
163#[allow(non_camel_case_types)]
164pub enum ExtCosts {
165    base = 0,
166    contract_loading_base = 1,
167    contract_loading_bytes = 2,
168    read_memory_base = 3,
169    read_memory_byte = 4,
170    write_memory_base = 5,
171    write_memory_byte = 6,
172    read_register_base = 7,
173    read_register_byte = 8,
174    write_register_base = 9,
175    write_register_byte = 10,
176    utf8_decoding_base = 11,
177    utf8_decoding_byte = 12,
178    utf16_decoding_base = 13,
179    utf16_decoding_byte = 14,
180    sha256_base = 15,
181    sha256_byte = 16,
182    keccak256_base = 17,
183    keccak256_byte = 18,
184    keccak512_base = 19,
185    keccak512_byte = 20,
186    ripemd160_base = 21,
187    ripemd160_block = 22,
188    ecrecover_base = 23,
189    log_base = 24,
190    log_byte = 25,
191    storage_write_base = 26,
192    storage_write_key_byte = 27,
193    storage_write_value_byte = 28,
194    storage_write_evicted_byte = 29,
195    storage_read_base = 30,
196    storage_read_key_byte = 31,
197    storage_read_value_byte = 32,
198    storage_remove_base = 33,
199    storage_remove_key_byte = 34,
200    storage_remove_ret_value_byte = 35,
201    storage_has_key_base = 36,
202    storage_has_key_byte = 37,
203    storage_iter_create_prefix_base = 38,
204    storage_iter_create_prefix_byte = 39,
205    storage_iter_create_range_base = 40,
206    storage_iter_create_from_byte = 41,
207    storage_iter_create_to_byte = 42,
208    storage_iter_next_base = 43,
209    storage_iter_next_key_byte = 44,
210    storage_iter_next_value_byte = 45,
211    touching_trie_node = 46,
212    read_cached_trie_node = 47,
213    promise_and_base = 48,
214    promise_and_per_promise = 49,
215    promise_return = 50,
216    validator_pledge_base = 51,
217    validator_total_pledge_base = 52,
218    alt_bn128_g1_multiexp_base = 53,
219    alt_bn128_g1_multiexp_element = 54,
220    alt_bn128_pairing_check_base = 55,
221    alt_bn128_pairing_check_element = 56,
222    alt_bn128_g1_sum_base = 57,
223    alt_bn128_g1_sum_element = 58,
224    ed25519_verify_base = 59,
225    ed25519_verify_byte = 60,
226    validator_power_base = 61,
227    validator_total_power_base = 62,
228}
229
230// Type of an action, used in fees logic.
231#[derive(
232    Copy,
233    Clone,
234    Hash,
235    PartialEq,
236    Eq,
237    Debug,
238    PartialOrd,
239    Ord,
240    strum::Display,
241    strum::EnumIter,
242    enum_map::Enum,
243)]
244#[allow(non_camel_case_types)]
245pub enum ActionCosts {
246    create_account = 0,
247    delete_account = 1,
248    deploy_contract_base = 2,
249    deploy_contract_byte = 3,
250    function_call_base = 4,
251    function_call_byte = 5,
252    transfer = 6,
253    pledge = 7,
254    add_full_access_key = 8,
255    add_function_call_key_base = 9,
256    add_function_call_key_byte = 10,
257    delete_key = 11,
258    new_action_receipt = 12,
259    new_data_receipt_base = 13,
260    new_data_receipt_byte = 14,
261    delegate = 15,
262    register_rsa2048_keys = 16,
263    create_rsa2048_challenge = 17,
264}
265
266impl ExtCosts {
267    pub fn gas(self, config: &ExtCostsConfig) -> Gas {
268        config.gas_cost(self)
269    }
270
271    pub fn compute(self, config: &ExtCostsConfig) -> Compute {
272        config.compute_cost(self)
273    }
274
275    pub fn param(&self) -> Parameter {
276        match self {
277            ExtCosts::base => Parameter::WasmBase,
278            ExtCosts::contract_loading_base => Parameter::WasmContractLoadingBase,
279            ExtCosts::contract_loading_bytes => Parameter::WasmContractLoadingBytes,
280            ExtCosts::read_memory_base => Parameter::WasmReadMemoryBase,
281            ExtCosts::read_memory_byte => Parameter::WasmReadMemoryByte,
282            ExtCosts::write_memory_base => Parameter::WasmWriteMemoryBase,
283            ExtCosts::write_memory_byte => Parameter::WasmWriteMemoryByte,
284            ExtCosts::read_register_base => Parameter::WasmReadRegisterBase,
285            ExtCosts::read_register_byte => Parameter::WasmReadRegisterByte,
286            ExtCosts::write_register_base => Parameter::WasmWriteRegisterBase,
287            ExtCosts::write_register_byte => Parameter::WasmWriteRegisterByte,
288            ExtCosts::utf8_decoding_base => Parameter::WasmUtf8DecodingBase,
289            ExtCosts::utf8_decoding_byte => Parameter::WasmUtf8DecodingByte,
290            ExtCosts::utf16_decoding_base => Parameter::WasmUtf16DecodingBase,
291            ExtCosts::utf16_decoding_byte => Parameter::WasmUtf16DecodingByte,
292            ExtCosts::sha256_base => Parameter::WasmSha256Base,
293            ExtCosts::sha256_byte => Parameter::WasmSha256Byte,
294            ExtCosts::keccak256_base => Parameter::WasmKeccak256Base,
295            ExtCosts::keccak256_byte => Parameter::WasmKeccak256Byte,
296            ExtCosts::keccak512_base => Parameter::WasmKeccak512Base,
297            ExtCosts::keccak512_byte => Parameter::WasmKeccak512Byte,
298            ExtCosts::ripemd160_base => Parameter::WasmRipemd160Base,
299            ExtCosts::ripemd160_block => Parameter::WasmRipemd160Block,
300            ExtCosts::ecrecover_base => Parameter::WasmEcrecoverBase,
301            ExtCosts::ed25519_verify_base => Parameter::WasmEd25519VerifyBase,
302            ExtCosts::ed25519_verify_byte => Parameter::WasmEd25519VerifyByte,
303            ExtCosts::log_base => Parameter::WasmLogBase,
304            ExtCosts::log_byte => Parameter::WasmLogByte,
305            ExtCosts::storage_write_base => Parameter::WasmStorageWriteBase,
306            ExtCosts::storage_write_key_byte => Parameter::WasmStorageWriteKeyByte,
307            ExtCosts::storage_write_value_byte => Parameter::WasmStorageWriteValueByte,
308            ExtCosts::storage_write_evicted_byte => Parameter::WasmStorageWriteEvictedByte,
309            ExtCosts::storage_read_base => Parameter::WasmStorageReadBase,
310            ExtCosts::storage_read_key_byte => Parameter::WasmStorageReadKeyByte,
311            ExtCosts::storage_read_value_byte => Parameter::WasmStorageReadValueByte,
312            ExtCosts::storage_remove_base => Parameter::WasmStorageRemoveBase,
313            ExtCosts::storage_remove_key_byte => Parameter::WasmStorageRemoveKeyByte,
314            ExtCosts::storage_remove_ret_value_byte => Parameter::WasmStorageRemoveRetValueByte,
315            ExtCosts::storage_has_key_base => Parameter::WasmStorageHasKeyBase,
316            ExtCosts::storage_has_key_byte => Parameter::WasmStorageHasKeyByte,
317            ExtCosts::storage_iter_create_prefix_base => Parameter::WasmStorageIterCreatePrefixBase,
318            ExtCosts::storage_iter_create_prefix_byte => Parameter::WasmStorageIterCreatePrefixByte,
319            ExtCosts::storage_iter_create_range_base => Parameter::WasmStorageIterCreateRangeBase,
320            ExtCosts::storage_iter_create_from_byte => Parameter::WasmStorageIterCreateFromByte,
321            ExtCosts::storage_iter_create_to_byte => Parameter::WasmStorageIterCreateToByte,
322            ExtCosts::storage_iter_next_base => Parameter::WasmStorageIterNextBase,
323            ExtCosts::storage_iter_next_key_byte => Parameter::WasmStorageIterNextKeyByte,
324            ExtCosts::storage_iter_next_value_byte => Parameter::WasmStorageIterNextValueByte,
325            ExtCosts::touching_trie_node => Parameter::WasmTouchingTrieNode,
326            ExtCosts::read_cached_trie_node => Parameter::WasmReadCachedTrieNode,
327            ExtCosts::promise_and_base => Parameter::WasmPromiseAndBase,
328            ExtCosts::promise_and_per_promise => Parameter::WasmPromiseAndPerPromise,
329            ExtCosts::promise_return => Parameter::WasmPromiseReturn,
330            ExtCosts::validator_pledge_base => Parameter::WasmValidatorPowerBase,
331            ExtCosts::validator_total_pledge_base => Parameter::WasmValidatorTotalPowerBase,
332            ExtCosts::alt_bn128_g1_multiexp_base => Parameter::WasmAltBn128G1MultiexpBase,
333            ExtCosts::alt_bn128_g1_multiexp_element => Parameter::WasmAltBn128G1MultiexpElement,
334            ExtCosts::alt_bn128_pairing_check_base => Parameter::WasmAltBn128PairingCheckBase,
335            ExtCosts::alt_bn128_pairing_check_element => Parameter::WasmAltBn128PairingCheckElement,
336            ExtCosts::alt_bn128_g1_sum_base => Parameter::WasmAltBn128G1SumBase,
337            ExtCosts::alt_bn128_g1_sum_element => Parameter::WasmAltBn128G1SumElement,
338            ExtCosts::validator_power_base => Parameter::WasmValidatorPledgeBase,
339            ExtCosts::validator_total_power_base => Parameter::WasmValidatorTotalPledgeBase,
340        }
341    }
342}
343
344#[derive(Debug, Clone, Hash, PartialEq, Eq)]
345pub struct RuntimeFeesConfig {
346    /// Gas fees for sending and executing actions.
347    pub action_fees: EnumMap<ActionCosts, Fee>,
348
349    /// Describes fees for storage.
350    pub storage_usage_config: StorageUsageConfig,
351
352    /// Fraction of the burnt gas to reward to the contract account for execution.
353    pub burnt_gas_reward: Rational32,
354
355    /// Pessimistic gas price inflation ratio.
356    pub pessimistic_gas_price_inflation_ratio: Rational32,
357}
358
359/// Describes cost of storage per block
360#[derive(Debug, Clone, Hash, PartialEq, Eq)]
361pub struct StorageUsageConfig {
362    /// Amount of yN per byte required to have on the account. See
363    /// <https://nomicon.io/Economics/README.html#state-pledge> for details.
364    pub storage_amount_per_byte: Balance,
365    /// Number of bytes for an account record, including rounding up for account id.
366    pub num_bytes_account: u64,
367    /// Additional number of bytes for a k/v record
368    pub num_extra_bytes_record: u64,
369}
370
371impl RuntimeFeesConfig {
372    /// Access action fee by `ActionCosts`.
373    pub fn fee(&self, cost: ActionCosts) -> &Fee {
374        &self.action_fees[cost]
375    }
376
377    pub fn test() -> Self {
378        Self {
379            storage_usage_config: StorageUsageConfig::test(),
380            burnt_gas_reward: Rational32::new(3, 10),
381            pessimistic_gas_price_inflation_ratio: Rational32::new(103, 100),
382            action_fees: enum_map::enum_map! {
383                ActionCosts::create_account => Fee {
384                    send_sir: 3_850_000_000_000,
385                    send_not_sir: 3_850_000_000_000,
386                    execution: 3_850_000_000_000,
387                },
388                ActionCosts::delete_account => Fee {
389                    send_sir: 147489000000,
390                    send_not_sir: 147489000000,
391                    execution: 147489000000,
392                },
393                ActionCosts::deploy_contract_base => Fee {
394                    send_sir: 184765750000,
395                    send_not_sir: 184765750000,
396                    execution: 184765750000,
397                },
398                ActionCosts::deploy_contract_byte => Fee {
399                    send_sir: 6812999,
400                    send_not_sir: 6812999,
401                    execution: 6812999,
402                },
403                ActionCosts::function_call_base => Fee {
404                    send_sir: 2319861500000,
405                    send_not_sir: 2319861500000,
406                    execution: 2319861500000,
407                },
408                ActionCosts::function_call_byte => Fee {
409                    send_sir: 2235934,
410                    send_not_sir: 2235934,
411                    execution: 2235934,
412                },
413                ActionCosts::transfer => Fee {
414                    send_sir: 115123062500,
415                    send_not_sir: 115123062500,
416                    execution: 115123062500,
417                },
418                ActionCosts::pledge => Fee {
419                    send_sir: 141715687500,
420                    send_not_sir: 141715687500,
421                    execution: 102217625000,
422                },
423                ActionCosts::add_full_access_key => Fee {
424                    send_sir: 101765125000,
425                    send_not_sir: 101765125000,
426                    execution: 101765125000,
427                },
428                ActionCosts::add_function_call_key_base => Fee {
429                    send_sir: 102217625000,
430                    send_not_sir: 102217625000,
431                    execution: 102217625000,
432                },
433                ActionCosts::add_function_call_key_byte => Fee {
434                    send_sir: 1925331,
435                    send_not_sir: 1925331,
436                    execution: 1925331,
437                },
438                ActionCosts::delete_key => Fee {
439                    send_sir: 94946625000,
440                    send_not_sir: 94946625000,
441                    execution: 94946625000,
442                },
443                ActionCosts::new_action_receipt => Fee {
444                    send_sir: 108059500000,
445                    send_not_sir: 108059500000,
446                    execution: 108059500000,
447                },
448                ActionCosts::new_data_receipt_base => Fee {
449                    send_sir: 4697339419375,
450                    send_not_sir: 4697339419375,
451                    execution: 4697339419375,
452                },
453                ActionCosts::new_data_receipt_byte => Fee {
454                    send_sir: 59357464,
455                    send_not_sir: 59357464,
456                    execution: 59357464,
457                },
458                ActionCosts::delegate => Fee {
459                    send_sir: 200_000_000_000,
460                    send_not_sir: 200_000_000_000,
461                    execution: 200_000_000_000,
462                },
463                ActionCosts::register_rsa2048_keys => Fee {
464                    send_sir: 101765125000,
465                    send_not_sir: 101765125000,
466                    execution: 101765125000,
467                },
468                ActionCosts::create_rsa2048_challenge => Fee {
469                    send_sir: 115123062500,
470                    send_not_sir: 115123062500,
471                    execution: 115123062500,
472                },
473            },
474        }
475    }
476
477    pub fn free() -> Self {
478        Self {
479            action_fees: enum_map::enum_map! {
480                _ => Fee { send_sir: 0, send_not_sir: 0, execution: 0 }
481            },
482            storage_usage_config: StorageUsageConfig::free(),
483            burnt_gas_reward: Rational32::from_integer(0),
484            pessimistic_gas_price_inflation_ratio: Rational32::from_integer(0),
485        }
486    }
487
488    /// The minimum amount of gas required to create and execute a new receipt with a function call
489    /// action.
490    /// This amount is used to determine how many receipts can be created, send and executed for
491    /// some amount of prepaid gas using function calls.
492    pub fn min_receipt_with_function_call_gas(&self) -> Gas {
493        self.fee(ActionCosts::new_action_receipt).min_send_and_exec_fee()
494            + self.fee(ActionCosts::function_call_base).min_send_and_exec_fee()
495    }
496}
497
498impl StorageUsageConfig {
499    pub fn test() -> Self {
500        Self {
501            num_bytes_account: 100,
502            num_extra_bytes_record: 40,
503            storage_amount_per_byte: 909 * 100_000_000_000_000_000,
504        }
505    }
506
507    pub(crate) fn free() -> StorageUsageConfig {
508        Self { num_bytes_account: 0, num_extra_bytes_record: 0, storage_amount_per_byte: 0 }
509    }
510}
511
512/// Helper functions for computing Transfer fees.
513/// In case of implicit account creation they include extra fees for the CreateAccount and
514/// AddFullAccessKey (for Utility account only) actions that are implicit.
515/// We can assume that no overflow will happen here.
516pub fn transfer_exec_fee(
517    cfg: &RuntimeFeesConfig,
518    implicit_account_creation_allowed: bool,
519    eth_implicit_accounts_enabled: bool,
520    receiver_account_type: AccountType,
521) -> Gas {
522    let transfer_fee = cfg.fee(ActionCosts::transfer).exec_fee();
523    match (implicit_account_creation_allowed, eth_implicit_accounts_enabled, receiver_account_type)
524    {
525        // Regular transfer to a named account.
526        (_, _, AccountType::Reserved) => transfer_fee,
527        // No account will be created, just a regular transfer.
528        (false, _, _) => transfer_fee,
529        // No account will be created, just a regular transfer.
530        (true, false, AccountType::EthAccount) => transfer_fee,
531        // Extra fee for the CreateAccount.
532        (true, true, AccountType::EthAccount) => {
533            transfer_fee + cfg.fee(ActionCosts::create_account).exec_fee()
534        }
535        // Extra fees for the CreateAccount and AddFullAccessKey.
536        (true, _, AccountType::UtilityAccount) => {
537            transfer_fee
538                + cfg.fee(ActionCosts::create_account).exec_fee()
539                + cfg.fee(ActionCosts::add_full_access_key).exec_fee()
540        }
541    }
542}
543
544pub fn transfer_send_fee(
545    cfg: &RuntimeFeesConfig,
546    sender_is_receiver: bool,
547    implicit_account_creation_allowed: bool,
548    eth_implicit_accounts_enabled: bool,
549    receiver_account_type: AccountType,
550) -> Gas {
551    let transfer_fee = cfg.fee(ActionCosts::transfer).send_fee(sender_is_receiver);
552    match (implicit_account_creation_allowed, eth_implicit_accounts_enabled, receiver_account_type)
553    {
554        // Regular transfer to a named account.
555        (_, _, AccountType::Reserved) => transfer_fee,
556        // No account will be created, just a regular transfer.
557        (false, _, _) => transfer_fee,
558        // No account will be created, just a regular transfer.
559        (true, false, AccountType::EthAccount) => transfer_fee,
560        // Extra fee for the CreateAccount.
561        (true, true, AccountType::EthAccount) => {
562            transfer_fee + cfg.fee(ActionCosts::create_account).send_fee(sender_is_receiver)
563        }
564        // Extra fees for the CreateAccount and AddFullAccessKey.
565        (true, _, AccountType::UtilityAccount) => {
566            transfer_fee
567                + cfg.fee(ActionCosts::create_account).send_fee(sender_is_receiver)
568                + cfg.fee(ActionCosts::add_full_access_key).send_fee(sender_is_receiver)
569        }
570    }
571}