use crate::{ActionCosts, ExtCosts, Fee, ParameterCost};
use near_account_id::AccountId;
use near_primitives_core::serialize::dec_format;
use near_primitives_core::types::{Balance, Gas};
use num_rational::Rational32;
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
pub struct RuntimeConfigView {
#[serde(with = "dec_format")]
pub storage_amount_per_byte: Balance,
pub transaction_costs: RuntimeFeesConfigView,
pub wasm_config: VMConfigView,
pub account_creation_config: AccountCreationConfigView,
}
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
pub struct RuntimeFeesConfigView {
pub action_receipt_creation_config: Fee,
pub data_receipt_creation_config: DataReceiptCreationConfigView,
pub action_creation_config: ActionCreationConfigView,
pub storage_usage_config: StorageUsageConfigView,
pub burnt_gas_reward: Rational32,
pub pessimistic_gas_price_inflation_ratio: Rational32,
}
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
pub struct AccountCreationConfigView {
pub min_allowed_top_level_account_length: u8,
pub registrar_account_id: AccountId,
}
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Hash, PartialEq, Eq)]
pub struct DataReceiptCreationConfigView {
pub base_cost: Fee,
pub cost_per_byte: Fee,
}
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Hash, PartialEq, Eq)]
pub struct ActionCreationConfigView {
pub create_account_cost: Fee,
pub deploy_contract_cost: Fee,
pub deploy_contract_cost_per_byte: Fee,
pub function_call_cost: Fee,
pub function_call_cost_per_byte: Fee,
pub transfer_cost: Fee,
pub stake_cost: Fee,
pub add_key_cost: AccessKeyCreationConfigView,
pub delete_key_cost: Fee,
pub delete_account_cost: Fee,
pub delegate_cost: Fee,
}
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Hash, PartialEq, Eq)]
pub struct AccessKeyCreationConfigView {
pub full_access_cost: Fee,
pub function_call_cost: Fee,
pub function_call_cost_per_byte: Fee,
}
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Hash, PartialEq, Eq)]
pub struct StorageUsageConfigView {
pub num_bytes_account: u64,
pub num_extra_bytes_record: u64,
}
impl From<crate::RuntimeConfig> for RuntimeConfigView {
fn from(config: crate::RuntimeConfig) -> Self {
Self {
storage_amount_per_byte: config.storage_amount_per_byte(),
transaction_costs: RuntimeFeesConfigView {
action_receipt_creation_config: config
.fees
.fee(ActionCosts::new_action_receipt)
.clone(),
data_receipt_creation_config: DataReceiptCreationConfigView {
base_cost: config.fees.fee(ActionCosts::new_data_receipt_base).clone(),
cost_per_byte: config.fees.fee(ActionCosts::new_data_receipt_byte).clone(),
},
action_creation_config: ActionCreationConfigView {
create_account_cost: config.fees.fee(ActionCosts::create_account).clone(),
deploy_contract_cost: config
.fees
.fee(ActionCosts::deploy_contract_base)
.clone(),
deploy_contract_cost_per_byte: config
.fees
.fee(ActionCosts::deploy_contract_byte)
.clone(),
function_call_cost: config.fees.fee(ActionCosts::function_call_base).clone(),
function_call_cost_per_byte: config
.fees
.fee(ActionCosts::function_call_byte)
.clone(),
transfer_cost: config.fees.fee(ActionCosts::transfer).clone(),
stake_cost: config.fees.fee(ActionCosts::stake).clone(),
add_key_cost: AccessKeyCreationConfigView {
full_access_cost: config.fees.fee(ActionCosts::add_full_access_key).clone(),
function_call_cost: config
.fees
.fee(ActionCosts::add_function_call_key_base)
.clone(),
function_call_cost_per_byte: config
.fees
.fee(ActionCosts::add_function_call_key_byte)
.clone(),
},
delete_key_cost: config.fees.fee(ActionCosts::delete_key).clone(),
delete_account_cost: config.fees.fee(ActionCosts::delete_account).clone(),
delegate_cost: config.fees.fee(ActionCosts::delegate).clone(),
},
storage_usage_config: StorageUsageConfigView {
num_bytes_account: config.fees.storage_usage_config.num_bytes_account,
num_extra_bytes_record: config.fees.storage_usage_config.num_extra_bytes_record,
},
burnt_gas_reward: config.fees.burnt_gas_reward,
pessimistic_gas_price_inflation_ratio: config
.fees
.pessimistic_gas_price_inflation_ratio,
},
wasm_config: VMConfigView::from(config.wasm_config),
account_creation_config: AccountCreationConfigView {
min_allowed_top_level_account_length: config
.account_creation_config
.min_allowed_top_level_account_length,
registrar_account_id: config.account_creation_config.registrar_account_id,
},
}
}
}
#[derive(Clone, Debug, Hash, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
pub struct VMConfigView {
pub ext_costs: ExtCostsConfigView,
pub grow_mem_cost: u32,
pub regular_op_cost: u32,
pub vm_kind: crate::vm::VMKind,
pub disable_9393_fix: bool,
pub storage_get_mode: crate::vm::StorageGetMode,
pub fix_contract_loading_cost: bool,
pub implicit_account_creation: bool,
pub math_extension: bool,
pub ed25519_verify: bool,
pub alt_bn128: bool,
pub function_call_weight: bool,
pub eth_implicit_accounts: bool,
pub limit_config: crate::vm::LimitConfig,
}
impl From<crate::vm::Config> for VMConfigView {
fn from(config: crate::vm::Config) -> Self {
Self {
ext_costs: ExtCostsConfigView::from(config.ext_costs),
grow_mem_cost: config.grow_mem_cost,
regular_op_cost: config.regular_op_cost,
disable_9393_fix: config.disable_9393_fix,
limit_config: config.limit_config,
storage_get_mode: config.storage_get_mode,
fix_contract_loading_cost: config.fix_contract_loading_cost,
implicit_account_creation: config.implicit_account_creation,
math_extension: config.math_extension,
ed25519_verify: config.ed25519_verify,
alt_bn128: config.alt_bn128,
function_call_weight: config.function_call_weight,
vm_kind: config.vm_kind,
eth_implicit_accounts: config.eth_implicit_accounts,
}
}
}
impl From<VMConfigView> for crate::vm::Config {
fn from(view: VMConfigView) -> Self {
Self {
ext_costs: crate::ExtCostsConfig::from(view.ext_costs),
grow_mem_cost: view.grow_mem_cost,
regular_op_cost: view.regular_op_cost,
disable_9393_fix: view.disable_9393_fix,
limit_config: view.limit_config,
storage_get_mode: view.storage_get_mode,
fix_contract_loading_cost: view.fix_contract_loading_cost,
implicit_account_creation: view.implicit_account_creation,
math_extension: view.math_extension,
ed25519_verify: view.ed25519_verify,
alt_bn128: view.alt_bn128,
function_call_weight: view.function_call_weight,
vm_kind: view.vm_kind,
eth_implicit_accounts: view.eth_implicit_accounts,
}
}
}
#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Hash, PartialEq, Eq)]
pub struct ExtCostsConfigView {
pub base: Gas,
pub contract_loading_base: Gas,
pub contract_loading_bytes: Gas,
pub read_memory_base: Gas,
pub read_memory_byte: Gas,
pub write_memory_base: Gas,
pub write_memory_byte: Gas,
pub read_register_base: Gas,
pub read_register_byte: Gas,
pub write_register_base: Gas,
pub write_register_byte: Gas,
pub utf8_decoding_base: Gas,
pub utf8_decoding_byte: Gas,
pub utf16_decoding_base: Gas,
pub utf16_decoding_byte: Gas,
pub sha256_base: Gas,
pub sha256_byte: Gas,
pub keccak256_base: Gas,
pub keccak256_byte: Gas,
pub keccak512_base: Gas,
pub keccak512_byte: Gas,
pub ripemd160_base: Gas,
pub ripemd160_block: Gas,
pub ed25519_verify_base: Gas,
pub ed25519_verify_byte: Gas,
pub ecrecover_base: Gas,
pub log_base: Gas,
pub log_byte: Gas,
pub storage_write_base: Gas,
pub storage_write_key_byte: Gas,
pub storage_write_value_byte: Gas,
pub storage_write_evicted_byte: Gas,
pub storage_read_base: Gas,
pub storage_read_key_byte: Gas,
pub storage_read_value_byte: Gas,
pub storage_remove_base: Gas,
pub storage_remove_key_byte: Gas,
pub storage_remove_ret_value_byte: Gas,
pub storage_has_key_base: Gas,
pub storage_has_key_byte: Gas,
pub storage_iter_create_prefix_base: Gas,
pub storage_iter_create_prefix_byte: Gas,
pub storage_iter_create_range_base: Gas,
pub storage_iter_create_from_byte: Gas,
pub storage_iter_create_to_byte: Gas,
pub storage_iter_next_base: Gas,
pub storage_iter_next_key_byte: Gas,
pub storage_iter_next_value_byte: Gas,
pub touching_trie_node: Gas,
pub read_cached_trie_node: Gas,
pub promise_and_base: Gas,
pub promise_and_per_promise: Gas,
pub promise_return: Gas,
pub validator_stake_base: Gas,
pub validator_total_stake_base: Gas,
pub contract_compile_base: Gas,
pub contract_compile_bytes: Gas,
pub alt_bn128_g1_multiexp_base: Gas,
pub alt_bn128_g1_multiexp_element: Gas,
pub alt_bn128_g1_sum_base: Gas,
pub alt_bn128_g1_sum_element: Gas,
pub alt_bn128_pairing_check_base: Gas,
pub alt_bn128_pairing_check_element: Gas,
}
impl From<crate::ExtCostsConfig> for ExtCostsConfigView {
fn from(config: crate::ExtCostsConfig) -> Self {
Self {
base: config.gas_cost(ExtCosts::base),
contract_loading_base: config.gas_cost(ExtCosts::contract_loading_base),
contract_loading_bytes: config.gas_cost(ExtCosts::contract_loading_bytes),
read_memory_base: config.gas_cost(ExtCosts::read_memory_base),
read_memory_byte: config.gas_cost(ExtCosts::read_memory_byte),
write_memory_base: config.gas_cost(ExtCosts::write_memory_base),
write_memory_byte: config.gas_cost(ExtCosts::write_memory_byte),
read_register_base: config.gas_cost(ExtCosts::read_register_base),
read_register_byte: config.gas_cost(ExtCosts::read_register_byte),
write_register_base: config.gas_cost(ExtCosts::write_register_base),
write_register_byte: config.gas_cost(ExtCosts::write_register_byte),
utf8_decoding_base: config.gas_cost(ExtCosts::utf8_decoding_base),
utf8_decoding_byte: config.gas_cost(ExtCosts::utf8_decoding_byte),
utf16_decoding_base: config.gas_cost(ExtCosts::utf16_decoding_base),
utf16_decoding_byte: config.gas_cost(ExtCosts::utf16_decoding_byte),
sha256_base: config.gas_cost(ExtCosts::sha256_base),
sha256_byte: config.gas_cost(ExtCosts::sha256_byte),
keccak256_base: config.gas_cost(ExtCosts::keccak256_base),
keccak256_byte: config.gas_cost(ExtCosts::keccak256_byte),
keccak512_base: config.gas_cost(ExtCosts::keccak512_base),
keccak512_byte: config.gas_cost(ExtCosts::keccak512_byte),
ripemd160_base: config.gas_cost(ExtCosts::ripemd160_base),
ripemd160_block: config.gas_cost(ExtCosts::ripemd160_block),
ed25519_verify_base: config.gas_cost(ExtCosts::ed25519_verify_base),
ed25519_verify_byte: config.gas_cost(ExtCosts::ed25519_verify_byte),
ecrecover_base: config.gas_cost(ExtCosts::ecrecover_base),
log_base: config.gas_cost(ExtCosts::log_base),
log_byte: config.gas_cost(ExtCosts::log_byte),
storage_write_base: config.gas_cost(ExtCosts::storage_write_base),
storage_write_key_byte: config.gas_cost(ExtCosts::storage_write_key_byte),
storage_write_value_byte: config.gas_cost(ExtCosts::storage_write_value_byte),
storage_write_evicted_byte: config.gas_cost(ExtCosts::storage_write_evicted_byte),
storage_read_base: config.gas_cost(ExtCosts::storage_read_base),
storage_read_key_byte: config.gas_cost(ExtCosts::storage_read_key_byte),
storage_read_value_byte: config.gas_cost(ExtCosts::storage_read_value_byte),
storage_remove_base: config.gas_cost(ExtCosts::storage_remove_base),
storage_remove_key_byte: config.gas_cost(ExtCosts::storage_remove_key_byte),
storage_remove_ret_value_byte: config.gas_cost(ExtCosts::storage_remove_ret_value_byte),
storage_has_key_base: config.gas_cost(ExtCosts::storage_has_key_base),
storage_has_key_byte: config.gas_cost(ExtCosts::storage_has_key_byte),
storage_iter_create_prefix_base: config
.gas_cost(ExtCosts::storage_iter_create_prefix_base),
storage_iter_create_prefix_byte: config
.gas_cost(ExtCosts::storage_iter_create_prefix_byte),
storage_iter_create_range_base: config
.gas_cost(ExtCosts::storage_iter_create_range_base),
storage_iter_create_from_byte: config.gas_cost(ExtCosts::storage_iter_create_from_byte),
storage_iter_create_to_byte: config.gas_cost(ExtCosts::storage_iter_create_to_byte),
storage_iter_next_base: config.gas_cost(ExtCosts::storage_iter_next_base),
storage_iter_next_key_byte: config.gas_cost(ExtCosts::storage_iter_next_key_byte),
storage_iter_next_value_byte: config.gas_cost(ExtCosts::storage_iter_next_value_byte),
touching_trie_node: config.gas_cost(ExtCosts::touching_trie_node),
read_cached_trie_node: config.gas_cost(ExtCosts::read_cached_trie_node),
promise_and_base: config.gas_cost(ExtCosts::promise_and_base),
promise_and_per_promise: config.gas_cost(ExtCosts::promise_and_per_promise),
promise_return: config.gas_cost(ExtCosts::promise_return),
validator_stake_base: config.gas_cost(ExtCosts::validator_stake_base),
validator_total_stake_base: config.gas_cost(ExtCosts::validator_total_stake_base),
alt_bn128_g1_multiexp_base: config.gas_cost(ExtCosts::alt_bn128_g1_multiexp_base),
alt_bn128_g1_multiexp_element: config.gas_cost(ExtCosts::alt_bn128_g1_multiexp_element),
alt_bn128_g1_sum_base: config.gas_cost(ExtCosts::alt_bn128_g1_sum_base),
alt_bn128_g1_sum_element: config.gas_cost(ExtCosts::alt_bn128_g1_sum_element),
alt_bn128_pairing_check_base: config.gas_cost(ExtCosts::alt_bn128_pairing_check_base),
alt_bn128_pairing_check_element: config
.gas_cost(ExtCosts::alt_bn128_pairing_check_element),
contract_compile_base: 0,
contract_compile_bytes: 0,
}
}
}
impl From<ExtCostsConfigView> for crate::ExtCostsConfig {
fn from(view: ExtCostsConfigView) -> Self {
let costs = enum_map::enum_map! {
ExtCosts::base => view.base,
ExtCosts::contract_loading_base => view.contract_loading_base,
ExtCosts::contract_loading_bytes => view.contract_loading_bytes,
ExtCosts::read_memory_base => view.read_memory_base,
ExtCosts::read_memory_byte => view.read_memory_byte,
ExtCosts::write_memory_base => view.write_memory_base,
ExtCosts::write_memory_byte => view.write_memory_byte,
ExtCosts::read_register_base => view.read_register_base,
ExtCosts::read_register_byte => view.read_register_byte,
ExtCosts::write_register_base => view.write_register_base,
ExtCosts::write_register_byte => view.write_register_byte,
ExtCosts::utf8_decoding_base => view.utf8_decoding_base,
ExtCosts::utf8_decoding_byte => view.utf8_decoding_byte,
ExtCosts::utf16_decoding_base => view.utf16_decoding_base,
ExtCosts::utf16_decoding_byte => view.utf16_decoding_byte,
ExtCosts::sha256_base => view.sha256_base,
ExtCosts::sha256_byte => view.sha256_byte,
ExtCosts::keccak256_base => view.keccak256_base,
ExtCosts::keccak256_byte => view.keccak256_byte,
ExtCosts::keccak512_base => view.keccak512_base,
ExtCosts::keccak512_byte => view.keccak512_byte,
ExtCosts::ripemd160_base => view.ripemd160_base,
ExtCosts::ripemd160_block => view.ripemd160_block,
ExtCosts::ed25519_verify_base => view.ed25519_verify_base,
ExtCosts::ed25519_verify_byte => view.ed25519_verify_byte,
ExtCosts::ecrecover_base => view.ecrecover_base,
ExtCosts::log_base => view.log_base,
ExtCosts::log_byte => view.log_byte,
ExtCosts::storage_write_base => view.storage_write_base,
ExtCosts::storage_write_key_byte => view.storage_write_key_byte,
ExtCosts::storage_write_value_byte => view.storage_write_value_byte,
ExtCosts::storage_write_evicted_byte => view.storage_write_evicted_byte,
ExtCosts::storage_read_base => view.storage_read_base,
ExtCosts::storage_read_key_byte => view.storage_read_key_byte,
ExtCosts::storage_read_value_byte => view.storage_read_value_byte,
ExtCosts::storage_remove_base => view.storage_remove_base,
ExtCosts::storage_remove_key_byte => view.storage_remove_key_byte,
ExtCosts::storage_remove_ret_value_byte => view.storage_remove_ret_value_byte,
ExtCosts::storage_has_key_base => view.storage_has_key_base,
ExtCosts::storage_has_key_byte => view.storage_has_key_byte,
ExtCosts::storage_iter_create_prefix_base => view.storage_iter_create_prefix_base,
ExtCosts::storage_iter_create_prefix_byte => view.storage_iter_create_prefix_byte,
ExtCosts::storage_iter_create_range_base => view.storage_iter_create_range_base,
ExtCosts::storage_iter_create_from_byte => view.storage_iter_create_from_byte,
ExtCosts::storage_iter_create_to_byte => view.storage_iter_create_to_byte,
ExtCosts::storage_iter_next_base => view.storage_iter_next_base,
ExtCosts::storage_iter_next_key_byte => view.storage_iter_next_key_byte,
ExtCosts::storage_iter_next_value_byte => view.storage_iter_next_value_byte,
ExtCosts::touching_trie_node => view.touching_trie_node,
ExtCosts::read_cached_trie_node => view.read_cached_trie_node,
ExtCosts::promise_and_base => view.promise_and_base,
ExtCosts::promise_and_per_promise => view.promise_and_per_promise,
ExtCosts::promise_return => view.promise_return,
ExtCosts::validator_stake_base => view.validator_stake_base,
ExtCosts::validator_total_stake_base => view.validator_total_stake_base,
ExtCosts::alt_bn128_g1_multiexp_base => view.alt_bn128_g1_multiexp_base,
ExtCosts::alt_bn128_g1_multiexp_element => view.alt_bn128_g1_multiexp_element,
ExtCosts::alt_bn128_g1_sum_base => view.alt_bn128_g1_sum_base,
ExtCosts::alt_bn128_g1_sum_element => view.alt_bn128_g1_sum_element,
ExtCosts::alt_bn128_pairing_check_base => view.alt_bn128_pairing_check_base,
ExtCosts::alt_bn128_pairing_check_element => view.alt_bn128_pairing_check_element,
}
.map(|_, value| ParameterCost { gas: value, compute: value });
Self { costs }
}
}
#[cfg(test)]
mod tests {
#[test]
#[cfg_attr(feature = "nightly", ignore)]
fn test_runtime_config_view() {
use crate::view::RuntimeConfigView;
use crate::RuntimeConfig;
use crate::RuntimeConfigStore;
use near_primitives_core::version::PROTOCOL_VERSION;
let config_store = RuntimeConfigStore::new(None);
let config = config_store.get_config(PROTOCOL_VERSION);
let view = RuntimeConfigView::from(RuntimeConfig::clone(config));
insta::assert_json_snapshot!(&view, { ".wasm_config.vm_kind" => "<REDACTED>"});
}
}