use crate::parameter::Parameter;
use enum_map::{EnumMap, enum_map};
use near_account_id::AccountType;
use near_primitives_core::account::{AccessKey, GasKeyInfo};
use near_primitives_core::trie_key::access_key_key_len;
use near_primitives_core::types::{Balance, Compute, Gas, NonceIndex};
use near_schema_checker_lib::ProtocolSchema;
use num_rational::Rational32;
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Hash, PartialEq, Eq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Fee {
pub send_sir: Gas,
pub send_not_sir: Gas,
pub execution: Gas,
}
impl Fee {
pub fn new(send_sir: u64, send_not_sir: u64, execution: u64) -> Self {
Self {
send_sir: Gas::from_gas(send_sir),
send_not_sir: Gas::from_gas(send_not_sir),
execution: Gas::from_gas(execution),
}
}
#[inline]
pub fn send_fee(&self, sir: bool) -> Gas {
if sir { self.send_sir } else { self.send_not_sir }
}
pub fn exec_fee(&self) -> Gas {
self.execution
}
pub fn min_send_and_exec_fee(&self) -> Gas {
std::cmp::min(self.send_sir, self.send_not_sir).checked_add(self.execution).unwrap()
}
fn test_value(value: u64) -> Self {
Self {
send_sir: Gas::from_gas(value),
send_not_sir: Gas::from_gas(value),
execution: Gas::from_gas(value),
}
}
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct ParameterCost {
pub gas: Gas,
pub compute: Compute,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct ExtCostsConfig {
pub costs: EnumMap<ExtCosts, ParameterCost>,
}
const SAFETY_MULTIPLIER: u64 = 3;
impl ExtCostsConfig {
pub fn gas_cost(&self, param: ExtCosts) -> Gas {
self.costs[param].gas
}
pub fn compute_cost(&self, param: ExtCosts) -> Compute {
self.costs[param].compute
}
pub fn test_with_undercharging_factor(factor: u64) -> ExtCostsConfig {
let costs = enum_map! {
ExtCosts::base => SAFETY_MULTIPLIER * 88256037,
ExtCosts::contract_loading_base => SAFETY_MULTIPLIER * 11815321,
ExtCosts::contract_loading_bytes => SAFETY_MULTIPLIER * 72250,
ExtCosts::read_memory_base => SAFETY_MULTIPLIER * 869954400,
ExtCosts::read_memory_byte => SAFETY_MULTIPLIER * 1267111,
ExtCosts::write_memory_base => SAFETY_MULTIPLIER * 934598287,
ExtCosts::write_memory_byte => SAFETY_MULTIPLIER * 907924,
ExtCosts::read_register_base => SAFETY_MULTIPLIER * 839055062,
ExtCosts::read_register_byte => SAFETY_MULTIPLIER * 32854,
ExtCosts::write_register_base => SAFETY_MULTIPLIER * 955174162,
ExtCosts::write_register_byte => SAFETY_MULTIPLIER * 1267188,
ExtCosts::utf8_decoding_base => SAFETY_MULTIPLIER * 1037259687,
ExtCosts::utf8_decoding_byte => SAFETY_MULTIPLIER * 97193493,
ExtCosts::utf16_decoding_base => SAFETY_MULTIPLIER * 1181104350,
ExtCosts::utf16_decoding_byte => SAFETY_MULTIPLIER * 54525831,
ExtCosts::sha256_base => SAFETY_MULTIPLIER * 1513656750,
ExtCosts::sha256_byte => SAFETY_MULTIPLIER * 8039117,
ExtCosts::keccak256_base => SAFETY_MULTIPLIER * 1959830425,
ExtCosts::keccak256_byte => SAFETY_MULTIPLIER * 7157035,
ExtCosts::keccak512_base => SAFETY_MULTIPLIER * 1937129412,
ExtCosts::keccak512_byte => SAFETY_MULTIPLIER * 12216567,
ExtCosts::ripemd160_base => SAFETY_MULTIPLIER * 284558362,
ExtCosts::ed25519_verify_base => SAFETY_MULTIPLIER * 1513656750,
ExtCosts::ed25519_verify_byte => SAFETY_MULTIPLIER * 7157035,
ExtCosts::ripemd160_block => SAFETY_MULTIPLIER * 226702528,
ExtCosts::ecrecover_base => SAFETY_MULTIPLIER * 1121789875000,
ExtCosts::log_base => SAFETY_MULTIPLIER * 1181104350,
ExtCosts::log_byte => SAFETY_MULTIPLIER * 4399597,
ExtCosts::storage_write_base => SAFETY_MULTIPLIER * 21398912000,
ExtCosts::storage_write_key_byte => SAFETY_MULTIPLIER * 23494289,
ExtCosts::storage_write_value_byte => SAFETY_MULTIPLIER * 10339513,
ExtCosts::storage_write_evicted_byte => SAFETY_MULTIPLIER * 10705769,
ExtCosts::storage_read_base => SAFETY_MULTIPLIER * 18785615250,
ExtCosts::storage_read_key_byte => SAFETY_MULTIPLIER * 10317511,
ExtCosts::storage_read_value_byte => SAFETY_MULTIPLIER * 1870335,
ExtCosts::storage_large_read_overhead_base => 0,
ExtCosts::storage_large_read_overhead_byte => 0,
ExtCosts::storage_remove_base => SAFETY_MULTIPLIER * 17824343500,
ExtCosts::storage_remove_key_byte => SAFETY_MULTIPLIER * 12740128,
ExtCosts::storage_remove_ret_value_byte => SAFETY_MULTIPLIER * 3843852,
ExtCosts::storage_has_key_base => SAFETY_MULTIPLIER * 18013298875,
ExtCosts::storage_has_key_byte => SAFETY_MULTIPLIER * 10263615,
ExtCosts::storage_iter_create_prefix_base => 0,
ExtCosts::storage_iter_create_prefix_byte => 0,
ExtCosts::storage_iter_create_range_base => 0,
ExtCosts::storage_iter_create_from_byte => 0,
ExtCosts::storage_iter_create_to_byte => 0,
ExtCosts::storage_iter_next_base => 0,
ExtCosts::storage_iter_next_key_byte => 0,
ExtCosts::storage_iter_next_value_byte => 0,
ExtCosts::touching_trie_node => SAFETY_MULTIPLIER * 5367318642,
ExtCosts::read_cached_trie_node => SAFETY_MULTIPLIER * 760_000_000,
ExtCosts::promise_and_base => SAFETY_MULTIPLIER * 488337800,
ExtCosts::promise_and_per_promise => SAFETY_MULTIPLIER * 1817392,
ExtCosts::promise_return => SAFETY_MULTIPLIER * 186717462,
ExtCosts::validator_stake_base => SAFETY_MULTIPLIER * 303944908800,
ExtCosts::validator_total_stake_base => SAFETY_MULTIPLIER * 303944908800,
ExtCosts::alt_bn128_g1_multiexp_base => 713_000_000_000,
ExtCosts::alt_bn128_g1_multiexp_element => 320_000_000_000,
ExtCosts::alt_bn128_pairing_check_base => 9_686_000_000_000,
ExtCosts::alt_bn128_pairing_check_element => 5_102_000_000_000,
ExtCosts::alt_bn128_g1_sum_base => 3_000_000_000,
ExtCosts::alt_bn128_g1_sum_element => 5_000_000_000,
ExtCosts::bls12381_p1_sum_base => SAFETY_MULTIPLIER * 5_500_000_000,
ExtCosts::bls12381_p1_sum_element => SAFETY_MULTIPLIER * 2_000_000_000,
ExtCosts::bls12381_p2_sum_base => SAFETY_MULTIPLIER * 6_200_000_000,
ExtCosts::bls12381_p2_sum_element => SAFETY_MULTIPLIER * 5_000_000_000,
ExtCosts::bls12381_g1_multiexp_base => SAFETY_MULTIPLIER * 5_500_000_000,
ExtCosts::bls12381_g1_multiexp_element => SAFETY_MULTIPLIER * 310_000_000_000,
ExtCosts::bls12381_g2_multiexp_base => SAFETY_MULTIPLIER * 6_200_000_000,
ExtCosts::bls12381_g2_multiexp_element => SAFETY_MULTIPLIER * 665_000_000_000,
ExtCosts::bls12381_map_fp_to_g1_base => SAFETY_MULTIPLIER * 500_000_000,
ExtCosts::bls12381_map_fp_to_g1_element => SAFETY_MULTIPLIER * 84_000_000_000,
ExtCosts::bls12381_map_fp2_to_g2_base => SAFETY_MULTIPLIER * 500_000_000,
ExtCosts::bls12381_map_fp2_to_g2_element => SAFETY_MULTIPLIER * 300_000_000_000,
ExtCosts::bls12381_pairing_base => SAFETY_MULTIPLIER * 710_000_000_000,
ExtCosts::bls12381_pairing_element => SAFETY_MULTIPLIER * 710_000_000_000,
ExtCosts::bls12381_p1_decompress_base => SAFETY_MULTIPLIER * 500_000_000,
ExtCosts::bls12381_p1_decompress_element => SAFETY_MULTIPLIER * 27_000_000_000,
ExtCosts::bls12381_p2_decompress_base => SAFETY_MULTIPLIER * 500_000_000,
ExtCosts::bls12381_p2_decompress_element => SAFETY_MULTIPLIER * 55_000_000_000,
ExtCosts::yield_create_base => 300_000_000_000_000,
ExtCosts::yield_create_byte => 300_000_000_000_000,
ExtCosts::yield_resume_base => 300_000_000_000_000,
ExtCosts::yield_resume_byte => 300_000_000_000_000,
}
.map(|_, value| ParameterCost { gas: Gas::from_gas(value), compute: value * factor });
ExtCostsConfig { costs }
}
pub fn test() -> ExtCostsConfig {
Self::test_with_undercharging_factor(1)
}
}
#[derive(
Copy,
Clone,
Hash,
PartialEq,
Eq,
Debug,
PartialOrd,
Ord,
strum::Display,
strum::EnumIter,
enum_map::Enum,
ProtocolSchema,
)]
#[allow(non_camel_case_types)]
pub enum ExtCosts {
base = 0,
contract_loading_base = 1,
contract_loading_bytes = 2,
read_memory_base = 3,
read_memory_byte = 4,
write_memory_base = 5,
write_memory_byte = 6,
read_register_base = 7,
read_register_byte = 8,
write_register_base = 9,
write_register_byte = 10,
utf8_decoding_base = 11,
utf8_decoding_byte = 12,
utf16_decoding_base = 13,
utf16_decoding_byte = 14,
sha256_base = 15,
sha256_byte = 16,
keccak256_base = 17,
keccak256_byte = 18,
keccak512_base = 19,
keccak512_byte = 20,
ripemd160_base = 21,
ripemd160_block = 22,
ecrecover_base = 23,
log_base = 24,
log_byte = 25,
storage_write_base = 26,
storage_write_key_byte = 27,
storage_write_value_byte = 28,
storage_write_evicted_byte = 29,
storage_read_base = 30,
storage_read_key_byte = 31,
storage_read_value_byte = 32,
storage_remove_base = 33,
storage_remove_key_byte = 34,
storage_remove_ret_value_byte = 35,
storage_has_key_base = 36,
storage_has_key_byte = 37,
storage_iter_create_prefix_base = 38,
storage_iter_create_prefix_byte = 39,
storage_iter_create_range_base = 40,
storage_iter_create_from_byte = 41,
storage_iter_create_to_byte = 42,
storage_iter_next_base = 43,
storage_iter_next_key_byte = 44,
storage_iter_next_value_byte = 45,
touching_trie_node = 46,
read_cached_trie_node = 47,
promise_and_base = 48,
promise_and_per_promise = 49,
promise_return = 50,
validator_stake_base = 51,
validator_total_stake_base = 52,
alt_bn128_g1_multiexp_base = 53,
alt_bn128_g1_multiexp_element = 54,
alt_bn128_pairing_check_base = 55,
alt_bn128_pairing_check_element = 56,
alt_bn128_g1_sum_base = 57,
alt_bn128_g1_sum_element = 58,
ed25519_verify_base = 59,
ed25519_verify_byte = 60,
yield_create_base = 61,
yield_create_byte = 62,
yield_resume_base = 63,
yield_resume_byte = 64,
bls12381_p1_sum_base = 65,
bls12381_p1_sum_element = 66,
bls12381_p2_sum_base = 67,
bls12381_p2_sum_element = 68,
bls12381_g1_multiexp_base = 69,
bls12381_g1_multiexp_element = 70,
bls12381_g2_multiexp_base = 71,
bls12381_g2_multiexp_element = 72,
bls12381_map_fp_to_g1_base = 73,
bls12381_map_fp_to_g1_element = 74,
bls12381_map_fp2_to_g2_base = 75,
bls12381_map_fp2_to_g2_element = 76,
bls12381_pairing_base = 77,
bls12381_pairing_element = 78,
bls12381_p1_decompress_base = 79,
bls12381_p1_decompress_element = 80,
bls12381_p2_decompress_base = 81,
bls12381_p2_decompress_element = 82,
storage_large_read_overhead_base = 83,
storage_large_read_overhead_byte = 84,
}
#[derive(
Copy,
Clone,
Hash,
PartialEq,
Eq,
Debug,
PartialOrd,
Ord,
strum::Display,
strum::EnumIter,
enum_map::Enum,
ProtocolSchema,
)]
#[allow(non_camel_case_types)]
pub enum ActionCosts {
create_account = 0,
delete_account = 1,
deploy_contract_base = 2,
deploy_contract_byte = 3,
function_call_base = 4,
function_call_byte = 5,
transfer = 6,
stake = 7,
add_full_access_key = 8,
add_function_call_key_base = 9,
add_function_call_key_byte = 10,
delete_key = 11,
new_action_receipt = 12,
new_data_receipt_base = 13,
new_data_receipt_byte = 14,
delegate = 15,
deploy_global_contract_base = 16,
deploy_global_contract_byte = 17,
use_global_contract_base = 18,
use_global_contract_byte = 19,
deterministic_state_init_base = 20,
deterministic_state_init_byte = 21,
deterministic_state_init_entry = 22,
gas_key_transfer_base = 23,
gas_key_byte = 24,
gas_key_nonce_write_base = 25,
}
impl ExtCosts {
pub fn gas(self, config: &ExtCostsConfig) -> Gas {
config.gas_cost(self)
}
pub fn compute(self, config: &ExtCostsConfig) -> Compute {
config.compute_cost(self)
}
pub fn param(&self) -> Parameter {
match self {
ExtCosts::base => Parameter::WasmBase,
ExtCosts::contract_loading_base => Parameter::WasmContractLoadingBase,
ExtCosts::contract_loading_bytes => Parameter::WasmContractLoadingBytes,
ExtCosts::read_memory_base => Parameter::WasmReadMemoryBase,
ExtCosts::read_memory_byte => Parameter::WasmReadMemoryByte,
ExtCosts::write_memory_base => Parameter::WasmWriteMemoryBase,
ExtCosts::write_memory_byte => Parameter::WasmWriteMemoryByte,
ExtCosts::read_register_base => Parameter::WasmReadRegisterBase,
ExtCosts::read_register_byte => Parameter::WasmReadRegisterByte,
ExtCosts::write_register_base => Parameter::WasmWriteRegisterBase,
ExtCosts::write_register_byte => Parameter::WasmWriteRegisterByte,
ExtCosts::utf8_decoding_base => Parameter::WasmUtf8DecodingBase,
ExtCosts::utf8_decoding_byte => Parameter::WasmUtf8DecodingByte,
ExtCosts::utf16_decoding_base => Parameter::WasmUtf16DecodingBase,
ExtCosts::utf16_decoding_byte => Parameter::WasmUtf16DecodingByte,
ExtCosts::sha256_base => Parameter::WasmSha256Base,
ExtCosts::sha256_byte => Parameter::WasmSha256Byte,
ExtCosts::keccak256_base => Parameter::WasmKeccak256Base,
ExtCosts::keccak256_byte => Parameter::WasmKeccak256Byte,
ExtCosts::keccak512_base => Parameter::WasmKeccak512Base,
ExtCosts::keccak512_byte => Parameter::WasmKeccak512Byte,
ExtCosts::ripemd160_base => Parameter::WasmRipemd160Base,
ExtCosts::ripemd160_block => Parameter::WasmRipemd160Block,
ExtCosts::ecrecover_base => Parameter::WasmEcrecoverBase,
ExtCosts::ed25519_verify_base => Parameter::WasmEd25519VerifyBase,
ExtCosts::ed25519_verify_byte => Parameter::WasmEd25519VerifyByte,
ExtCosts::log_base => Parameter::WasmLogBase,
ExtCosts::log_byte => Parameter::WasmLogByte,
ExtCosts::storage_write_base => Parameter::WasmStorageWriteBase,
ExtCosts::storage_write_key_byte => Parameter::WasmStorageWriteKeyByte,
ExtCosts::storage_write_value_byte => Parameter::WasmStorageWriteValueByte,
ExtCosts::storage_write_evicted_byte => Parameter::WasmStorageWriteEvictedByte,
ExtCosts::storage_read_base => Parameter::WasmStorageReadBase,
ExtCosts::storage_read_key_byte => Parameter::WasmStorageReadKeyByte,
ExtCosts::storage_read_value_byte => Parameter::WasmStorageReadValueByte,
ExtCosts::storage_large_read_overhead_base => {
Parameter::WasmStorageLargeReadOverheadBase
}
ExtCosts::storage_large_read_overhead_byte => {
Parameter::WasmStorageLargeReadOverheadByte
}
ExtCosts::storage_remove_base => Parameter::WasmStorageRemoveBase,
ExtCosts::storage_remove_key_byte => Parameter::WasmStorageRemoveKeyByte,
ExtCosts::storage_remove_ret_value_byte => Parameter::WasmStorageRemoveRetValueByte,
ExtCosts::storage_has_key_base => Parameter::WasmStorageHasKeyBase,
ExtCosts::storage_has_key_byte => Parameter::WasmStorageHasKeyByte,
ExtCosts::storage_iter_create_prefix_base => Parameter::WasmStorageIterCreatePrefixBase,
ExtCosts::storage_iter_create_prefix_byte => Parameter::WasmStorageIterCreatePrefixByte,
ExtCosts::storage_iter_create_range_base => Parameter::WasmStorageIterCreateRangeBase,
ExtCosts::storage_iter_create_from_byte => Parameter::WasmStorageIterCreateFromByte,
ExtCosts::storage_iter_create_to_byte => Parameter::WasmStorageIterCreateToByte,
ExtCosts::storage_iter_next_base => Parameter::WasmStorageIterNextBase,
ExtCosts::storage_iter_next_key_byte => Parameter::WasmStorageIterNextKeyByte,
ExtCosts::storage_iter_next_value_byte => Parameter::WasmStorageIterNextValueByte,
ExtCosts::touching_trie_node => Parameter::WasmTouchingTrieNode,
ExtCosts::read_cached_trie_node => Parameter::WasmReadCachedTrieNode,
ExtCosts::promise_and_base => Parameter::WasmPromiseAndBase,
ExtCosts::promise_and_per_promise => Parameter::WasmPromiseAndPerPromise,
ExtCosts::promise_return => Parameter::WasmPromiseReturn,
ExtCosts::validator_stake_base => Parameter::WasmValidatorStakeBase,
ExtCosts::validator_total_stake_base => Parameter::WasmValidatorTotalStakeBase,
ExtCosts::alt_bn128_g1_multiexp_base => Parameter::WasmAltBn128G1MultiexpBase,
ExtCosts::alt_bn128_g1_multiexp_element => Parameter::WasmAltBn128G1MultiexpElement,
ExtCosts::alt_bn128_pairing_check_base => Parameter::WasmAltBn128PairingCheckBase,
ExtCosts::alt_bn128_pairing_check_element => Parameter::WasmAltBn128PairingCheckElement,
ExtCosts::alt_bn128_g1_sum_base => Parameter::WasmAltBn128G1SumBase,
ExtCosts::alt_bn128_g1_sum_element => Parameter::WasmAltBn128G1SumElement,
ExtCosts::yield_create_base => Parameter::WasmYieldCreateBase,
ExtCosts::yield_create_byte => Parameter::WasmYieldCreateByte,
ExtCosts::yield_resume_base => Parameter::WasmYieldResumeBase,
ExtCosts::yield_resume_byte => Parameter::WasmYieldResumeByte,
ExtCosts::bls12381_p1_sum_base => Parameter::WasmBls12381P1SumBase,
ExtCosts::bls12381_p1_sum_element => Parameter::WasmBls12381P1SumElement,
ExtCosts::bls12381_p2_sum_base => Parameter::WasmBls12381P2SumBase,
ExtCosts::bls12381_p2_sum_element => Parameter::WasmBls12381P2SumElement,
ExtCosts::bls12381_g1_multiexp_base => Parameter::WasmBls12381G1MultiexpBase,
ExtCosts::bls12381_g1_multiexp_element => Parameter::WasmBls12381G1MultiexpElement,
ExtCosts::bls12381_g2_multiexp_base => Parameter::WasmBls12381G2MultiexpBase,
ExtCosts::bls12381_g2_multiexp_element => Parameter::WasmBls12381G2MultiexpElement,
ExtCosts::bls12381_map_fp_to_g1_base => Parameter::WasmBls12381MapFpToG1Base,
ExtCosts::bls12381_map_fp_to_g1_element => Parameter::WasmBls12381MapFpToG1Element,
ExtCosts::bls12381_map_fp2_to_g2_base => Parameter::WasmBls12381MapFp2ToG2Base,
ExtCosts::bls12381_map_fp2_to_g2_element => Parameter::WasmBls12381MapFp2ToG2Element,
ExtCosts::bls12381_pairing_base => Parameter::WasmBls12381PairingBase,
ExtCosts::bls12381_pairing_element => Parameter::WasmBls12381PairingElement,
ExtCosts::bls12381_p1_decompress_base => Parameter::WasmBls12381P1DecompressBase,
ExtCosts::bls12381_p1_decompress_element => Parameter::WasmBls12381P1DecompressElement,
ExtCosts::bls12381_p2_decompress_base => Parameter::WasmBls12381P2DecompressBase,
ExtCosts::bls12381_p2_decompress_element => Parameter::WasmBls12381P2DecompressElement,
}
}
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct RuntimeFeesConfig {
pub action_fees: EnumMap<ActionCosts, Fee>,
pub storage_usage_config: StorageUsageConfig,
pub burnt_gas_reward: Rational32,
pub pessimistic_gas_price_inflation_ratio: Rational32,
pub gas_refund_penalty: Rational32,
pub min_gas_refund_penalty: Gas,
}
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct StorageUsageConfig {
pub storage_amount_per_byte: Balance,
pub num_bytes_account: u64,
pub num_extra_bytes_record: u64,
pub global_contract_storage_amount_per_byte: Balance,
}
impl RuntimeFeesConfig {
pub fn fee(&self, cost: ActionCosts) -> &Fee {
&self.action_fees[cost]
}
pub fn test() -> Self {
Self {
storage_usage_config: StorageUsageConfig::test(),
burnt_gas_reward: Rational32::new(3, 10),
pessimistic_gas_price_inflation_ratio: Rational32::new(103, 100),
gas_refund_penalty: Rational32::new(5, 100),
min_gas_refund_penalty: Gas::from_teragas(1),
action_fees: enum_map::enum_map! {
ActionCosts::create_account => Fee::test_value(3_850_000_000_000),
ActionCosts::delete_account => Fee::test_value(147489000000),
ActionCosts::deploy_contract_base => Fee::test_value(184765750000),
ActionCosts::deploy_contract_byte => Fee::test_value(6812999),
ActionCosts::function_call_base => Fee::test_value(2319861500000),
ActionCosts::function_call_byte => Fee::test_value(2235934),
ActionCosts::transfer => Fee::test_value(115123062500),
ActionCosts::stake => Fee::new(141715687500, 141715687500, 102217625000),
ActionCosts::add_full_access_key => Fee::test_value(101765125000),
ActionCosts::add_function_call_key_base => Fee::test_value(102217625000),
ActionCosts::add_function_call_key_byte => Fee::test_value(1925331),
ActionCosts::delete_key => Fee::test_value(94946625000),
ActionCosts::new_action_receipt => Fee::test_value(108059500000),
ActionCosts::new_data_receipt_base => Fee::test_value(4697339419375),
ActionCosts::new_data_receipt_byte => Fee::test_value(59357464),
ActionCosts::delegate => Fee::test_value(200_000_000_000),
ActionCosts::deploy_global_contract_base => Fee::test_value(184_765_750_000),
ActionCosts::deploy_global_contract_byte => Fee::new(6_812_999, 6_812_999, 70_000_000),
ActionCosts::use_global_contract_base => Fee::test_value(184_765_750_000),
ActionCosts::use_global_contract_byte => Fee::new(6_812_999, 47_683_715, 64_572_944),
ActionCosts::deterministic_state_init_base => Fee::new(3_850_000_000_000, 3_850_000_000_000, 4_080_000_000_000),
ActionCosts::deterministic_state_init_byte => Fee::new(72_000_000, 72_000_000, 70_000_000),
ActionCosts::deterministic_state_init_entry => Fee::new(0, 0, 200_000_000_000),
ActionCosts::gas_key_transfer_base => Fee::new(115_123_062_500, 115_123_062_500, 235_676_644_250),
ActionCosts::gas_key_byte => Fee::new(59_357_464, 59_357_464, 101_435_400),
ActionCosts::gas_key_nonce_write_base => Fee::new(0, 0, 64_196_736_000),
},
}
}
pub fn free() -> Self {
Self {
action_fees: enum_map::enum_map! {
_ => Fee::new(0, 0, 0)
},
storage_usage_config: StorageUsageConfig::free(),
burnt_gas_reward: Rational32::from_integer(0),
pessimistic_gas_price_inflation_ratio: Rational32::from_integer(0),
gas_refund_penalty: Rational32::from_integer(0),
min_gas_refund_penalty: Gas::ZERO,
}
}
pub fn min_receipt_with_function_call_gas(&self) -> Gas {
self.fee(ActionCosts::new_action_receipt)
.min_send_and_exec_fee()
.checked_add(self.fee(ActionCosts::function_call_base).min_send_and_exec_fee())
.unwrap()
}
pub fn gas_penalty_for_gas_refund(&self, gas_refund: Gas) -> Gas {
let relative_cost = Gas::from_gas(
(u128::from(gas_refund.as_gas()) * *self.gas_refund_penalty.numer() as u128
/ *self.gas_refund_penalty.denom() as u128)
.try_into()
.unwrap(),
);
let penalty = std::cmp::max(relative_cost, self.min_gas_refund_penalty);
std::cmp::min(penalty, gas_refund)
}
}
impl StorageUsageConfig {
pub fn test() -> Self {
Self {
num_bytes_account: 100,
num_extra_bytes_record: 40,
storage_amount_per_byte: Balance::from_yoctonear(909 * 100_000_000_000_000_000),
global_contract_storage_amount_per_byte: Balance::from_yoctonear(
100_000_000_000_000_000_000,
),
}
}
pub(crate) fn free() -> StorageUsageConfig {
Self {
num_bytes_account: 0,
num_extra_bytes_record: 0,
storage_amount_per_byte: Balance::ZERO,
global_contract_storage_amount_per_byte: Balance::ZERO,
}
}
}
pub fn transfer_exec_fee(
cfg: &RuntimeFeesConfig,
eth_implicit_accounts_enabled: bool,
receiver_account_type: AccountType,
) -> Gas {
let transfer_fee = cfg.fee(ActionCosts::transfer).exec_fee();
match (eth_implicit_accounts_enabled, receiver_account_type) {
(_, AccountType::NamedAccount) => transfer_fee,
(false, AccountType::EthImplicitAccount) => transfer_fee,
(true, AccountType::EthImplicitAccount) => {
transfer_fee.checked_add(cfg.fee(ActionCosts::create_account).exec_fee()).unwrap()
}
(_, AccountType::NearImplicitAccount) => transfer_fee
.checked_add(cfg.fee(ActionCosts::create_account).exec_fee())
.unwrap()
.checked_add(cfg.fee(ActionCosts::add_full_access_key).exec_fee())
.unwrap(),
(_, AccountType::NearDeterministicAccount) => {
transfer_fee.checked_add(cfg.fee(ActionCosts::create_account).exec_fee()).unwrap()
}
}
}
pub fn transfer_send_fee(
cfg: &RuntimeFeesConfig,
sender_is_receiver: bool,
eth_implicit_accounts_enabled: bool,
receiver_account_type: AccountType,
) -> Gas {
let transfer_fee = cfg.fee(ActionCosts::transfer).send_fee(sender_is_receiver);
match (eth_implicit_accounts_enabled, receiver_account_type) {
(_, AccountType::NamedAccount) => transfer_fee,
(false, AccountType::EthImplicitAccount) => transfer_fee,
(true, AccountType::EthImplicitAccount) => transfer_fee
.checked_add(cfg.fee(ActionCosts::create_account).send_fee(sender_is_receiver))
.unwrap(),
(_, AccountType::NearImplicitAccount) => transfer_fee
.checked_add(cfg.fee(ActionCosts::create_account).send_fee(sender_is_receiver))
.unwrap()
.checked_add(cfg.fee(ActionCosts::add_full_access_key).send_fee(sender_is_receiver))
.unwrap(),
(_, AccountType::NearDeterministicAccount) => transfer_fee
.checked_add(cfg.fee(ActionCosts::create_account).send_fee(sender_is_receiver))
.unwrap(),
}
}
pub struct GasKeyTransferFee {
pub base: Gas,
pub per_byte: Gas,
}
impl GasKeyTransferFee {
pub fn total(&self) -> Gas {
self.base.checked_add(self.per_byte).unwrap()
}
}
pub fn gas_key_transfer_send_fee(
cfg: &RuntimeFeesConfig,
sender_is_receiver: bool,
public_key_len: usize,
) -> GasKeyTransferFee {
let base = cfg.fee(ActionCosts::gas_key_transfer_base).send_fee(sender_is_receiver);
let per_byte = cfg
.fee(ActionCosts::gas_key_byte)
.send_fee(sender_is_receiver)
.checked_mul(public_key_len as u64)
.unwrap();
GasKeyTransferFee { base, per_byte }
}
pub fn gas_key_transfer_exec_fee(
cfg: &RuntimeFeesConfig,
account_id_len: usize,
public_key_len: usize,
) -> GasKeyTransferFee {
let base = cfg.fee(ActionCosts::gas_key_transfer_base).exec_fee();
let trie_key_len = access_key_key_len(account_id_len, public_key_len);
let estimated_value_len = AccessKey::min_gas_key_borsh_len();
let per_byte = cfg
.fee(ActionCosts::gas_key_byte)
.exec_fee()
.checked_mul((trie_key_len + estimated_value_len) as u64)
.unwrap();
GasKeyTransferFee { base, per_byte }
}
pub struct GasKeyAddFee {
pub base: Gas,
pub per_byte: Gas,
}
impl GasKeyAddFee {
pub fn total(&self) -> Gas {
self.base.checked_add(self.per_byte).unwrap()
}
}
pub fn gas_key_add_key_send_fee(cfg: &RuntimeFeesConfig, sender_is_receiver: bool) -> Gas {
cfg.fee(ActionCosts::gas_key_byte)
.send_fee(sender_is_receiver)
.checked_mul(GasKeyInfo::borsh_len() as u64)
.unwrap()
}
pub fn gas_key_add_key_exec_fee(
cfg: &RuntimeFeesConfig,
account_id_len: usize,
public_key_len: usize,
num_nonces: NonceIndex,
) -> GasKeyAddFee {
let num_nonces = num_nonces as u64;
let base =
cfg.fee(ActionCosts::gas_key_nonce_write_base).exec_fee().checked_mul(num_nonces).unwrap();
let nonce_key_len =
access_key_key_len(account_id_len, public_key_len) + std::mem::size_of::<NonceIndex>();
let per_byte = cfg
.fee(ActionCosts::gas_key_byte)
.exec_fee()
.checked_mul((nonce_key_len + AccessKey::NONCE_VALUE_LEN) as u64)
.unwrap()
.checked_mul(num_nonces)
.unwrap();
GasKeyAddFee { base, per_byte }
}