diff --git a/chain/indexer/src/streamer/utils.rs b/chain/indexer/src/streamer/utils.rs index 5a1e92c6c25..6def1506d29 100644 --- a/chain/indexer/src/streamer/utils.rs +++ b/chain/indexer/src/streamer/utils.rs @@ -25,7 +25,7 @@ pub(crate) async fn convert_transactions_sir_into_local_receipts( txs.into_iter() .map(|tx| { let cost = tx_cost( - &runtime_config.fees, + &runtime_config, &near_primitives::transaction::Transaction { signer_id: tx.transaction.signer_id.clone(), public_key: tx.transaction.public_key.clone(), diff --git a/core/primitives/src/views.rs b/core/primitives/src/views.rs index 199dca94311..558b8977588 100644 --- a/core/primitives/src/views.rs +++ b/core/primitives/src/views.rs @@ -1252,10 +1252,7 @@ impl TryFrom for Action { Action::DeleteAccount(DeleteAccountAction { beneficiary_id }) } ActionView::Delegate { delegate_action, signature } => { - Action::Delegate(SignedDelegateAction { - delegate_action: delegate_action, - signature, - }) + Action::Delegate(SignedDelegateAction { delegate_action, signature }) } }) } diff --git a/integration-tests/src/node/runtime_node.rs b/integration-tests/src/node/runtime_node.rs index d7c25ab5023..980ae626c3f 100644 --- a/integration-tests/src/node/runtime_node.rs +++ b/integration-tests/src/node/runtime_node.rs @@ -109,7 +109,7 @@ mod tests { let (alice1, bob1) = (node.view_balance(&alice).unwrap(), node.view_balance(&bob).unwrap()); node_user.send_money(alice.clone(), bob.clone(), 1).unwrap(); let runtime_config = node.client.as_ref().read().unwrap().runtime_config.clone(); - let fee_helper = FeeHelper::new(runtime_config.fees, node.genesis().config.min_gas_price); + let fee_helper = FeeHelper::new(runtime_config, node.genesis().config.min_gas_price); let transfer_cost = fee_helper.transfer_cost(); let (alice2, bob2) = (node.view_balance(&alice).unwrap(), node.view_balance(&bob).unwrap()); assert_eq!(alice2, alice1 - 1 - transfer_cost); diff --git a/integration-tests/src/tests/client/features/delegate_action.rs b/integration-tests/src/tests/client/features/delegate_action.rs index 6bcd84ddf14..f086000f630 100644 --- a/integration-tests/src/tests/client/features/delegate_action.rs +++ b/integration-tests/src/tests/client/features/delegate_action.rs @@ -228,14 +228,15 @@ fn check_meta_tx_fn_call( // dynamic cost. The contract reward can be inferred from that. // static send gas is paid and burnt upfront - let static_send_gas = fee_helper.cfg.fee(ActionCosts::new_action_receipt).send_fee(false) - + num_fn_calls as u64 * fee_helper.cfg.fee(ActionCosts::function_call_base).send_fee(false) - + msg_len * fee_helper.cfg.fee(ActionCosts::function_call_byte).send_fee(false); + let static_send_gas = fee_helper.cfg().fee(ActionCosts::new_action_receipt).send_fee(false) + + num_fn_calls as u64 + * fee_helper.cfg().fee(ActionCosts::function_call_base).send_fee(false) + + msg_len * fee_helper.cfg().fee(ActionCosts::function_call_byte).send_fee(false); // static execution gas burnt in the same receipt as the function calls but // it doesn't contribute to the contract reward - let static_exec_gas = fee_helper.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + num_fn_calls as u64 * fee_helper.cfg.fee(ActionCosts::function_call_base).exec_fee() - + msg_len * fee_helper.cfg.fee(ActionCosts::function_call_byte).exec_fee(); + let static_exec_gas = fee_helper.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + num_fn_calls as u64 * fee_helper.cfg().fee(ActionCosts::function_call_base).exec_fee() + + msg_len * fee_helper.cfg().fee(ActionCosts::function_call_byte).exec_fee(); // calculate contract rewards as reward("gas burnt in fn call receipt" - "static exec costs") let gas_burnt_for_function_call = diff --git a/integration-tests/src/tests/standard_cases/mod.rs b/integration-tests/src/tests/standard_cases/mod.rs index f7dd2586282..2fe939a0bcb 100644 --- a/integration-tests/src/tests/standard_cases/mod.rs +++ b/integration-tests/src/tests/standard_cases/mod.rs @@ -35,7 +35,7 @@ use testlib::runtime_utils::{ const FUNCTION_CALL_AMOUNT: Balance = TESTING_INIT_BALANCE / 10; pub(crate) fn fee_helper(node: &impl Node) -> FeeHelper { - FeeHelper::new(RuntimeConfig::test().fees, node.genesis().config.min_gas_price) + FeeHelper::new(RuntimeConfig::test(), node.genesis().config.min_gas_price) } /// Adds given access key to the given account_id using signer2. @@ -404,9 +404,9 @@ pub fn trying_to_create_implicit_account(node: impl Node) { let cost = fee_helper.create_account_transfer_full_key_cost_fail_on_create_account() + fee_helper.gas_to_balance( - fee_helper.cfg.fee(ActionCosts::create_account).send_fee(false) + fee_helper.cfg().fee(ActionCosts::create_account).send_fee(false) + fee_helper - .cfg + .cfg() .fee(near_primitives::config::ActionCosts::add_full_access_key) .send_fee(false), ); diff --git a/integration-tests/src/tests/test_errors.rs b/integration-tests/src/tests/test_errors.rs index 8ee81b2edb7..36c11125976 100644 --- a/integration-tests/src/tests/test_errors.rs +++ b/integration-tests/src/tests/test_errors.rs @@ -15,6 +15,7 @@ use near_primitives::transaction::{ use near_primitives::version::PROTOCOL_VERSION; use nearcore::config::{GenesisExt, TESTING_INIT_BALANCE, TESTING_INIT_STAKE}; use nearcore::load_test_config; +use node_runtime::config::RuntimeConfig; use testlib::runtime_utils::{alice_account, bob_account}; fn start_node() -> ThreadNode { @@ -68,7 +69,7 @@ fn test_deliver_tx_error_log() { let runtime_config_store = RuntimeConfigStore::new(None); let runtime_config = runtime_config_store.get_config(PROTOCOL_VERSION); let fee_helper = testlib::fees_utils::FeeHelper::new( - runtime_config.fees.clone(), + RuntimeConfig::clone(&runtime_config), node.genesis().config.min_gas_price, ); let signer = diff --git a/nearcore/tests/economics.rs b/nearcore/tests/economics.rs index 197b07ac3e4..e5e05051e92 100644 --- a/nearcore/tests/economics.rs +++ b/nearcore/tests/economics.rs @@ -64,13 +64,12 @@ fn calc_total_supply(env: &mut TestEnv) -> u128 { fn test_burn_mint() { let genesis = build_genesis(); let mut env = setup_env(&genesis); - let transaction_costs = env.clients[0] + let config = env.clients[0] .runtime_adapter .get_protocol_config(&EpochId::default()) .unwrap() - .runtime_config - .fees; - let fee_helper = FeeHelper::new(transaction_costs, genesis.config.min_gas_price); + .runtime_config; + let fee_helper = FeeHelper::new(config, genesis.config.min_gas_price); let signer = InMemorySigner::from_seed("test0".parse().unwrap(), KeyType::ED25519, "test0"); let initial_total_supply = env.chain_genesis.total_supply; let genesis_hash = *env.clients[0].chain.genesis().hash(); diff --git a/runtime/runtime/src/actions.rs b/runtime/runtime/src/actions.rs index a9c65e55ab4..0ff274a9522 100644 --- a/runtime/runtime/src/actions.rs +++ b/runtime/runtime/src/actions.rs @@ -685,7 +685,7 @@ pub(crate) fn apply_delegate_action( // Therefore Relayer should verify DelegateAction before submitting it because it spends the attached deposit. let prepaid_send_fees = total_prepaid_send_fees( - &apply_state.config.fees, + &apply_state.config, &action_receipt.actions, apply_state.current_protocol_version, )?; @@ -709,7 +709,7 @@ fn receipt_required_gas(apply_state: &ApplyState, receipt: &Receipt) -> Result { let mut required_gas = safe_add_gas( total_prepaid_exec_fees( - &apply_state.config.fees, + &apply_state.config, &action_receipt.actions, &receipt.receiver_id, apply_state.current_protocol_version, diff --git a/runtime/runtime/src/balance_checker.rs b/runtime/runtime/src/balance_checker.rs index ce50f108871..8b963c56221 100644 --- a/runtime/runtime/src/balance_checker.rs +++ b/runtime/runtime/src/balance_checker.rs @@ -9,7 +9,7 @@ use near_primitives::errors::{ BalanceMismatchError, IntegerOverflowError, RuntimeError, StorageError, }; use near_primitives::receipt::{Receipt, ReceiptEnum}; -use near_primitives::runtime::fees::RuntimeFeesConfig; +use near_primitives::runtime::config::RuntimeConfig; use near_primitives::transaction::SignedTransaction; use near_primitives::trie_key::TrieKey; use near_primitives::types::{AccountId, Balance}; @@ -37,7 +37,7 @@ fn get_delayed_receipts( /// Calculates and returns cost of a receipt. fn receipt_cost( - transaction_costs: &RuntimeFeesConfig, + config: &RuntimeConfig, current_protocol_version: ProtocolVersion, receipt: &Receipt, ) -> Result { @@ -46,9 +46,9 @@ fn receipt_cost( let mut total_cost = total_deposit(&action_receipt.actions)?; if !AccountId::is_system(&receipt.predecessor_id) { let mut total_gas = safe_add_gas( - transaction_costs.fee(ActionCosts::new_action_receipt).exec_fee(), + config.fees.fee(ActionCosts::new_action_receipt).exec_fee(), total_prepaid_exec_fees( - transaction_costs, + config, &action_receipt.actions, &receipt.receiver_id, current_protocol_version, @@ -58,7 +58,7 @@ fn receipt_cost( total_gas = safe_add_gas( total_gas, total_prepaid_send_fees( - transaction_costs, + config, &action_receipt.actions, current_protocol_version, )?, @@ -74,12 +74,12 @@ fn receipt_cost( /// Calculates and returns total cost of all the receipts. fn total_receipts_cost( - transaction_costs: &RuntimeFeesConfig, + config: &RuntimeConfig, current_protocol_version: ProtocolVersion, receipts: &[Receipt], ) -> Result { receipts.iter().try_fold(0, |accumulator, receipt| { - let cost = receipt_cost(transaction_costs, current_protocol_version, receipt)?; + let cost = receipt_cost(config, current_protocol_version, receipt)?; safe_add_balance(accumulator, cost) }) } @@ -101,7 +101,7 @@ fn total_accounts_balance( /// Calculates and returns total costs of all the postponed receipts. fn total_postponed_receipts_cost( state: &dyn TrieAccess, - transaction_costs: &RuntimeFeesConfig, + config: &RuntimeConfig, current_protocol_version: ProtocolVersion, receipt_ids: &HashSet<(AccountId, crate::CryptoHash)>, ) -> Result { @@ -109,14 +109,14 @@ fn total_postponed_receipts_cost( let (account_id, receipt_id) = item; let cost = match get_postponed_receipt(state, account_id, *receipt_id)? { None => return Ok(total), - Some(receipt) => receipt_cost(transaction_costs, current_protocol_version, &receipt)?, + Some(receipt) => receipt_cost(config, current_protocol_version, &receipt)?, }; safe_add_balance(total, cost).map_err(|_| RuntimeError::UnexpectedIntegerOverflow) }) } pub(crate) fn check_balance( - transaction_costs: &RuntimeFeesConfig, + config: &RuntimeConfig, final_state: &TrieUpdate, validator_accounts_update: &Option, incoming_receipts: &[Receipt], @@ -173,7 +173,7 @@ pub(crate) fn check_balance( let final_accounts_balance = total_accounts_balance(final_state, &all_accounts_ids)?; // Receipts let receipts_cost = |receipts: &[Receipt]| -> Result { - total_receipts_cost(transaction_costs, current_protocol_version, receipts) + total_receipts_cost(config, current_protocol_version, receipts) }; let incoming_receipts_balance = receipts_cost(incoming_receipts)?; let outgoing_receipts_balance = receipts_cost(outgoing_receipts)?; @@ -210,13 +210,13 @@ pub(crate) fn check_balance( let initial_postponed_receipts_balance = total_postponed_receipts_cost( initial_state, - transaction_costs, + config, current_protocol_version, &all_potential_postponed_receipt_ids, )?; let final_postponed_receipts_balance = total_postponed_receipts_cost( final_state, - transaction_costs, + config, current_protocol_version, &all_potential_postponed_receipt_ids, )?; @@ -268,7 +268,6 @@ mod tests { use near_crypto::{InMemorySigner, KeyType}; use near_primitives::hash::{hash, CryptoHash}; use near_primitives::receipt::ActionReceipt; - use near_primitives::runtime::fees::RuntimeFeesConfig; use near_primitives::test_utils::account_new; use near_primitives::transaction::{Action, TransferAction}; use near_primitives::types::{MerkleHash, StateChangeCause}; @@ -291,9 +290,8 @@ mod tests { let tries = create_tries(); let root = MerkleHash::default(); let final_state = tries.new_trie_update(ShardUId::single_shard(), root); - let transaction_costs = RuntimeFeesConfig::test(); check_balance( - &transaction_costs, + &RuntimeConfig::test(), &final_state, &None, &[], @@ -310,9 +308,8 @@ mod tests { let tries = create_tries(); let root = MerkleHash::default(); let final_state = tries.new_trie_update(ShardUId::single_shard(), root); - let transaction_costs = RuntimeFeesConfig::test(); let err = check_balance( - &transaction_costs, + &RuntimeConfig::test(), &final_state, &None, &[Receipt::new_balance_refund(&alice_account(), 1000)], @@ -371,9 +368,8 @@ mod tests { }, ); - let transaction_costs = RuntimeFeesConfig::test(); check_balance( - &transaction_costs, + &RuntimeConfig::test(), &final_state, &None, &[Receipt::new_balance_refund(&account_id, refund_balance)], @@ -392,13 +388,14 @@ mod tests { let initial_balance = TESTING_INIT_BALANCE / 2; let deposit = 500_000_000; let gas_price = 100; - let cfg = RuntimeFeesConfig::test(); - let exec_gas = cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + cfg.fee(ActionCosts::transfer).exec_fee(); - let send_gas = cfg.fee(ActionCosts::new_action_receipt).send_fee(false) - + cfg.fee(ActionCosts::transfer).send_fee(false); - let contract_reward = send_gas as u128 * *cfg.burnt_gas_reward.numer() as u128 * gas_price - / (*cfg.burnt_gas_reward.denom() as u128); + let cfg = RuntimeConfig::test(); + let fees = &cfg.fees; + let exec_gas = fees.fee(ActionCosts::new_action_receipt).exec_fee() + + fees.fee(ActionCosts::transfer).exec_fee(); + let send_gas = fees.fee(ActionCosts::new_action_receipt).send_fee(false) + + fees.fee(ActionCosts::transfer).send_fee(false); + let contract_reward = send_gas as u128 * *fees.burnt_gas_reward.numer() as u128 * gas_price + / (*fees.burnt_gas_reward.denom() as u128); let total_validator_reward = send_gas as Balance * gas_price - contract_reward; let final_state = prepare_state_change( @@ -495,10 +492,9 @@ mod tests { }), }; - let transaction_costs = RuntimeFeesConfig::test(); assert_eq!( check_balance( - &transaction_costs, + &RuntimeConfig::test(), &initial_state, &None, &[receipt], diff --git a/runtime/runtime/src/config.rs b/runtime/runtime/src/config.rs index 095274d4146..380c4be63a4 100644 --- a/runtime/runtime/src/config.rs +++ b/runtime/runtime/src/config.rs @@ -10,7 +10,7 @@ use near_primitives::errors::IntegerOverflowError; // Just re-exporting RuntimeConfig for backwards compatibility. pub use near_primitives::num_rational::Rational32; pub use near_primitives::runtime::config::RuntimeConfig; -use near_primitives::runtime::fees::{transfer_exec_fee, transfer_send_fee, RuntimeFeesConfig}; +use near_primitives::runtime::fees::{transfer_exec_fee, transfer_send_fee}; use near_primitives::transaction::{ Action, AddKeyAction, DeployContractAction, FunctionCallAction, Transaction, }; @@ -73,30 +73,29 @@ macro_rules! safe_add_balance_apply { /// Total sum of gas that needs to be burnt to send these actions. pub fn total_send_fees( - config: &RuntimeFeesConfig, + config: &RuntimeConfig, sender_is_receiver: bool, actions: &[Action], receiver_id: &AccountId, current_protocol_version: ProtocolVersion, ) -> Result { let mut result = 0; + let fees = &config.fees; for action in actions { use Action::*; let delta = match action { - CreateAccount(_) => { - config.fee(ActionCosts::create_account).send_fee(sender_is_receiver) - } + CreateAccount(_) => fees.fee(ActionCosts::create_account).send_fee(sender_is_receiver), DeployContract(DeployContractAction { code }) => { let num_bytes = code.len() as u64; - config.fee(ActionCosts::deploy_contract_base).send_fee(sender_is_receiver) - + config.fee(ActionCosts::deploy_contract_byte).send_fee(sender_is_receiver) + fees.fee(ActionCosts::deploy_contract_base).send_fee(sender_is_receiver) + + fees.fee(ActionCosts::deploy_contract_byte).send_fee(sender_is_receiver) * num_bytes } FunctionCall(FunctionCallAction { method_name, args, .. }) => { let num_bytes = method_name.as_bytes().len() as u64 + args.len() as u64; - config.fee(ActionCosts::function_call_base).send_fee(sender_is_receiver) - + config.fee(ActionCosts::function_call_byte).send_fee(sender_is_receiver) + fees.fee(ActionCosts::function_call_base).send_fee(sender_is_receiver) + + fees.fee(ActionCosts::function_call_byte).send_fee(sender_is_receiver) * num_bytes } Transfer(_) => { @@ -104,9 +103,9 @@ pub fn total_send_fees( let is_receiver_implicit = checked_feature!("stable", ImplicitAccountCreation, current_protocol_version) && receiver_id.is_implicit(); - transfer_send_fee(config, sender_is_receiver, is_receiver_implicit) + transfer_send_fee(fees, sender_is_receiver, is_receiver_implicit) } - Stake(_) => config.fee(ActionCosts::stake).send_fee(sender_is_receiver), + Stake(_) => fees.fee(ActionCosts::stake).send_fee(sender_is_receiver), AddKey(AddKeyAction { access_key, .. }) => match &access_key.permission { AccessKeyPermission::FunctionCall(call_perm) => { let num_bytes = call_perm @@ -115,22 +114,20 @@ pub fn total_send_fees( // Account for null-terminating characters. .map(|name| name.as_bytes().len() as u64 + 1) .sum::(); - config.fee(ActionCosts::add_function_call_key_base).send_fee(sender_is_receiver) + fees.fee(ActionCosts::add_function_call_key_base).send_fee(sender_is_receiver) + num_bytes - * config + * fees .fee(ActionCosts::add_function_call_key_byte) .send_fee(sender_is_receiver) } AccessKeyPermission::FullAccess => { - config.fee(ActionCosts::add_full_access_key).send_fee(sender_is_receiver) + fees.fee(ActionCosts::add_full_access_key).send_fee(sender_is_receiver) } }, - DeleteKey(_) => config.fee(ActionCosts::delete_key).send_fee(sender_is_receiver), - DeleteAccount(_) => { - config.fee(ActionCosts::delete_account).send_fee(sender_is_receiver) - } + DeleteKey(_) => fees.fee(ActionCosts::delete_key).send_fee(sender_is_receiver), + DeleteAccount(_) => fees.fee(ActionCosts::delete_account).send_fee(sender_is_receiver), Delegate(signed_delegate_action) => { - let delegate_cost = config.fee(ActionCosts::delegate).send_fee(sender_is_receiver); + let delegate_cost = fees.fee(ActionCosts::delegate).send_fee(sender_is_receiver); let delegate_action = &signed_delegate_action.delegate_action; delegate_cost @@ -154,12 +151,11 @@ pub fn total_send_fees( /// need to be prepaid. All other actions burn send fees directly, so calling this function /// with other actions will return 0. pub fn total_prepaid_send_fees( - config: &RuntimeFeesConfig, + config: &RuntimeConfig, actions: &[Action], current_protocol_version: ProtocolVersion, ) -> Result { let mut result = 0; - for action in actions { use Action::*; let delta = match action { @@ -183,33 +179,33 @@ pub fn total_prepaid_send_fees( } pub fn exec_fee( - config: &RuntimeFeesConfig, + config: &RuntimeConfig, action: &Action, receiver_id: &AccountId, current_protocol_version: ProtocolVersion, ) -> Gas { use Action::*; - + let fees = &config.fees; match action { - CreateAccount(_) => config.fee(ActionCosts::create_account).exec_fee(), + CreateAccount(_) => fees.fee(ActionCosts::create_account).exec_fee(), DeployContract(DeployContractAction { code }) => { let num_bytes = code.len() as u64; - config.fee(ActionCosts::deploy_contract_base).exec_fee() - + config.fee(ActionCosts::deploy_contract_byte).exec_fee() * num_bytes + fees.fee(ActionCosts::deploy_contract_base).exec_fee() + + fees.fee(ActionCosts::deploy_contract_byte).exec_fee() * num_bytes } FunctionCall(FunctionCallAction { method_name, args, .. }) => { let num_bytes = method_name.as_bytes().len() as u64 + args.len() as u64; - config.fee(ActionCosts::function_call_base).exec_fee() - + config.fee(ActionCosts::function_call_byte).exec_fee() * num_bytes + fees.fee(ActionCosts::function_call_base).exec_fee() + + fees.fee(ActionCosts::function_call_byte).exec_fee() * num_bytes } Transfer(_) => { // Account for implicit account creation let is_receiver_implicit = checked_feature!("stable", ImplicitAccountCreation, current_protocol_version) && receiver_id.is_implicit(); - transfer_exec_fee(config, is_receiver_implicit) + transfer_exec_fee(fees, is_receiver_implicit) } - Stake(_) => config.fee(ActionCosts::stake).exec_fee(), + Stake(_) => fees.fee(ActionCosts::stake).exec_fee(), AddKey(AddKeyAction { access_key, .. }) => match &access_key.permission { AccessKeyPermission::FunctionCall(call_perm) => { let num_bytes = call_perm @@ -218,29 +214,29 @@ pub fn exec_fee( // Account for null-terminating characters. .map(|name| name.as_bytes().len() as u64 + 1) .sum::(); - config.fee(ActionCosts::add_function_call_key_base).exec_fee() - + num_bytes * config.fee(ActionCosts::add_function_call_key_byte).exec_fee() + fees.fee(ActionCosts::add_function_call_key_base).exec_fee() + + num_bytes * fees.fee(ActionCosts::add_function_call_key_byte).exec_fee() } AccessKeyPermission::FullAccess => { - config.fee(ActionCosts::add_full_access_key).exec_fee() + fees.fee(ActionCosts::add_full_access_key).exec_fee() } }, - DeleteKey(_) => config.fee(ActionCosts::delete_key).exec_fee(), - DeleteAccount(_) => config.fee(ActionCosts::delete_account).exec_fee(), - Delegate(_) => config.fee(ActionCosts::delegate).exec_fee(), + DeleteKey(_) => fees.fee(ActionCosts::delete_key).exec_fee(), + DeleteAccount(_) => fees.fee(ActionCosts::delete_account).exec_fee(), + Delegate(_) => fees.fee(ActionCosts::delegate).exec_fee(), } } /// Returns transaction costs for a given transaction. pub fn tx_cost( - config: &RuntimeFeesConfig, + config: &RuntimeConfig, transaction: &Transaction, gas_price: Balance, sender_is_receiver: bool, current_protocol_version: ProtocolVersion, ) -> Result { - let mut gas_burnt: Gas = - config.fee(ActionCosts::new_action_receipt).send_fee(sender_is_receiver); + let fees = &config.fees; + let mut gas_burnt: Gas = fees.fee(ActionCosts::new_action_receipt).send_fee(sender_is_receiver); gas_burnt = safe_add_gas( gas_burnt, total_send_fees( @@ -258,7 +254,7 @@ pub fn tx_cost( // If signer is equals to receiver the receipt will be processed at the same block as this // transaction. Otherwise it will processed in the next block and the gas might be inflated. let initial_receipt_hop = if transaction.signer_id == transaction.receiver_id { 0 } else { 1 }; - let minimum_new_receipt_gas = config.min_receipt_with_function_call_gas(); + let minimum_new_receipt_gas = fees.min_receipt_with_function_call_gas(); // In case the config is free, we don't care about the maximum depth. let receipt_gas_price = if gas_price == 0 { 0 @@ -269,13 +265,13 @@ pub fn tx_cost( .map_err(|_| IntegerOverflowError {})?; safe_gas_price_inflated( gas_price, - config.pessimistic_gas_price_inflation_ratio, + fees.pessimistic_gas_price_inflation_ratio, inflation_exponent, )? }; let mut gas_remaining = - safe_add_gas(prepaid_gas, config.fee(ActionCosts::new_action_receipt).exec_fee())?; + safe_add_gas(prepaid_gas, fees.fee(ActionCosts::new_action_receipt).exec_fee())?; gas_remaining = safe_add_gas( gas_remaining, total_prepaid_exec_fees( @@ -294,12 +290,13 @@ pub fn tx_cost( /// Total sum of gas that would need to be burnt before we start executing the given actions. pub fn total_prepaid_exec_fees( - config: &RuntimeFeesConfig, + config: &RuntimeConfig, actions: &[Action], receiver_id: &AccountId, current_protocol_version: ProtocolVersion, ) -> Result { let mut result = 0; + let fees = &config.fees; for action in actions { let mut delta; // In case of Action::Delegate it's needed to add Gas which is required for the inner actions. @@ -320,7 +317,7 @@ pub fn total_prepaid_exec_fees( current_protocol_version, ), )?; - delta = safe_add_gas(delta, config.fee(ActionCosts::new_action_receipt).exec_fee())?; + delta = safe_add_gas(delta, fees.fee(ActionCosts::new_action_receipt).exec_fee())?; } else { delta = exec_fee(config, action, receiver_id, current_protocol_version); } diff --git a/runtime/runtime/src/lib.rs b/runtime/runtime/src/lib.rs index c2cbef9ec08..7ec032a1ae6 100644 --- a/runtime/runtime/src/lib.rs +++ b/runtime/runtime/src/lib.rs @@ -22,7 +22,7 @@ use near_primitives::receipt::{ ActionReceipt, DataReceipt, DelayedReceiptIndices, Receipt, ReceiptEnum, ReceivedData, }; pub use near_primitives::runtime::apply_state::ApplyState; -use near_primitives::runtime::fees::RuntimeFeesConfig; +use near_primitives::runtime::config::RuntimeConfig; use near_primitives::runtime::migration_data::{MigrationData, MigrationFlags}; use near_primitives::sandbox::state_patch::SandboxStatePatch; use near_primitives::state_record::StateRecord; @@ -299,7 +299,7 @@ impl Runtime { epoch_info_provider: &dyn EpochInfoProvider, ) -> Result { let exec_fees = exec_fee( - &apply_state.config.fees, + &apply_state.config, action, &receipt.receiver_id, apply_state.current_protocol_version, @@ -614,7 +614,7 @@ impl Runtime { action_receipt, &mut result, apply_state.current_protocol_version, - &apply_state.config.fees, + &apply_state.config, )? }; stats.gas_deficit_amount = safe_add_balance(stats.gas_deficit_amount, gas_deficit_amount)?; @@ -773,25 +773,21 @@ impl Runtime { action_receipt: &ActionReceipt, result: &mut ActionResult, current_protocol_version: ProtocolVersion, - transaction_costs: &RuntimeFeesConfig, + config: &RuntimeConfig, ) -> Result { let total_deposit = total_deposit(&action_receipt.actions)?; let prepaid_gas = safe_add_gas( total_prepaid_gas(&action_receipt.actions)?, - total_prepaid_send_fees( - transaction_costs, - &action_receipt.actions, - current_protocol_version, - )?, + total_prepaid_send_fees(config, &action_receipt.actions, current_protocol_version)?, )?; let prepaid_exec_gas = safe_add_gas( total_prepaid_exec_fees( - transaction_costs, + config, &action_receipt.actions, &receipt.receiver_id, current_protocol_version, )?, - transaction_costs.fee(ActionCosts::new_action_receipt).exec_fee(), + config.fees.fee(ActionCosts::new_action_receipt).exec_fee(), )?; let deposit_refund = if result.result.is_err() { total_deposit } else { 0 }; let gas_refund = if result.result.is_err() { @@ -1463,7 +1459,7 @@ impl Runtime { } check_balance( - &apply_state.config.fees, + &apply_state.config, &state_update, validator_accounts_update, incoming_receipts, @@ -2255,7 +2251,7 @@ mod tests { let expected_gas_burnt = safe_add_gas( apply_state.config.fees.fee(ActionCosts::new_action_receipt).exec_fee(), total_prepaid_exec_fees( - &apply_state.config.fees, + &apply_state.config, &actions, &alice_account(), PROTOCOL_VERSION, @@ -2324,7 +2320,7 @@ mod tests { let expected_gas_burnt = safe_add_gas( apply_state.config.fees.fee(ActionCosts::new_action_receipt).exec_fee(), total_prepaid_exec_fees( - &apply_state.config.fees, + &apply_state.config, &actions, &alice_account(), PROTOCOL_VERSION, diff --git a/runtime/runtime/src/verifier.rs b/runtime/runtime/src/verifier.rs index 74f4f511ed9..30454b3168f 100644 --- a/runtime/runtime/src/verifier.rs +++ b/runtime/runtime/src/verifier.rs @@ -123,7 +123,7 @@ pub fn validate_transaction( let sender_is_receiver = &transaction.receiver_id == signer_id; - tx_cost(&config.fees, transaction, gas_price, sender_is_receiver, current_protocol_version) + tx_cost(&config, transaction, gas_price, sender_is_receiver, current_protocol_version) .map_err(|_| InvalidTxError::CostOverflow.into()) } diff --git a/test-utils/testlib/src/fees_utils.rs b/test-utils/testlib/src/fees_utils.rs index 18d6f9a91ff..8aa654d9cf3 100644 --- a/test-utils/testlib/src/fees_utils.rs +++ b/test-utils/testlib/src/fees_utils.rs @@ -1,25 +1,30 @@ //! Helper functions to compute the costs of certain actions assuming they succeed and the only //! actions in the transaction batch. use near_primitives::config::ActionCosts; +use near_primitives::runtime::config::RuntimeConfig; use near_primitives::runtime::fees::RuntimeFeesConfig; use near_primitives::transaction::Action; use near_primitives::types::{AccountId, Balance, Gas}; use near_primitives::version::PROTOCOL_VERSION; pub struct FeeHelper { - pub cfg: RuntimeFeesConfig, + pub rt_cfg: RuntimeConfig, pub gas_price: Balance, } impl FeeHelper { - pub fn new(cfg: RuntimeFeesConfig, gas_price: Balance) -> Self { - Self { cfg, gas_price } + pub fn new(rt_cfg: RuntimeConfig, gas_price: Balance) -> Self { + Self { rt_cfg, gas_price } + } + + pub fn cfg(&self) -> &RuntimeFeesConfig { + &self.rt_cfg.fees } pub fn gas_to_balance_inflated(&self, gas: Gas) -> Balance { gas as Balance - * (self.gas_price * (*self.cfg.pessimistic_gas_price_inflation_ratio.numer() as u128) - / (*self.cfg.pessimistic_gas_price_inflation_ratio.denom() as u128)) + * (self.gas_price * (*self.cfg().pessimistic_gas_price_inflation_ratio.numer() as u128) + / (*self.cfg().pessimistic_gas_price_inflation_ratio.denom() as u128)) } pub fn gas_to_balance(&self, gas: Gas) -> Balance { @@ -27,28 +32,28 @@ impl FeeHelper { } pub fn gas_burnt_to_reward(&self, gas_burnt: Gas) -> Balance { - let gas_reward = gas_burnt * *self.cfg.burnt_gas_reward.numer() as u64 - / *self.cfg.burnt_gas_reward.denom() as u64; + let gas_reward = gas_burnt * *self.cfg().burnt_gas_reward.numer() as u64 + / *self.cfg().burnt_gas_reward.denom() as u64; self.gas_to_balance(gas_reward) } pub fn create_account_cost(&self) -> Balance { - let exec_gas = self.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + self.cfg.fee(ActionCosts::create_account).exec_fee(); - let send_gas = self.cfg.fee(ActionCosts::new_action_receipt).send_fee(false) - + self.cfg.fee(ActionCosts::create_account).send_fee(false); + let exec_gas = self.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + self.cfg().fee(ActionCosts::create_account).exec_fee(); + let send_gas = self.cfg().fee(ActionCosts::new_action_receipt).send_fee(false) + + self.cfg().fee(ActionCosts::create_account).send_fee(false); self.gas_to_balance(exec_gas + send_gas) } pub fn create_account_transfer_full_key_fee(&self) -> Gas { - let exec_gas = self.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + self.cfg.fee(ActionCosts::create_account).exec_fee() - + self.cfg.fee(ActionCosts::transfer).exec_fee() - + self.cfg.fee(ActionCosts::add_full_access_key).exec_fee(); - let send_gas = self.cfg.fee(ActionCosts::new_action_receipt).send_fee(false) - + self.cfg.fee(ActionCosts::create_account).send_fee(false) - + self.cfg.fee(ActionCosts::transfer).send_fee(false) - + self.cfg.fee(ActionCosts::add_full_access_key).send_fee(false); + let exec_gas = self.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + self.cfg().fee(ActionCosts::create_account).exec_fee() + + self.cfg().fee(ActionCosts::transfer).exec_fee() + + self.cfg().fee(ActionCosts::add_full_access_key).exec_fee(); + let send_gas = self.cfg().fee(ActionCosts::new_action_receipt).send_fee(false) + + self.cfg().fee(ActionCosts::create_account).send_fee(false) + + self.cfg().fee(ActionCosts::transfer).send_fee(false) + + self.cfg().fee(ActionCosts::add_full_access_key).send_fee(false); exec_gas + send_gas } @@ -57,56 +62,56 @@ impl FeeHelper { } pub fn create_account_transfer_full_key_cost_no_reward(&self) -> Balance { - let exec_gas = self.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + self.cfg.fee(ActionCosts::create_account).exec_fee() - + self.cfg.fee(ActionCosts::transfer).exec_fee() - + self.cfg.fee(ActionCosts::add_full_access_key).exec_fee(); - let send_gas = self.cfg.fee(ActionCosts::new_action_receipt).send_fee(false) - + self.cfg.fee(ActionCosts::create_account).send_fee(false) - + self.cfg.fee(ActionCosts::transfer).send_fee(false) - + self.cfg.fee(ActionCosts::add_full_access_key).send_fee(false); + let exec_gas = self.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + self.cfg().fee(ActionCosts::create_account).exec_fee() + + self.cfg().fee(ActionCosts::transfer).exec_fee() + + self.cfg().fee(ActionCosts::add_full_access_key).exec_fee(); + let send_gas = self.cfg().fee(ActionCosts::new_action_receipt).send_fee(false) + + self.cfg().fee(ActionCosts::create_account).send_fee(false) + + self.cfg().fee(ActionCosts::transfer).send_fee(false) + + self.cfg().fee(ActionCosts::add_full_access_key).send_fee(false); self.gas_to_balance(send_gas) + self.gas_to_balance_inflated(exec_gas) } pub fn create_account_transfer_full_key_cost_fail_on_create_account(&self) -> Balance { - let exec_gas = self.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + self.cfg.fee(ActionCosts::create_account).exec_fee(); - let send_gas = self.cfg.fee(ActionCosts::new_action_receipt).send_fee(false) - + self.cfg.fee(ActionCosts::create_account).send_fee(false) - + self.cfg.fee(ActionCosts::transfer).send_fee(false) - + self.cfg.fee(ActionCosts::add_full_access_key).send_fee(false); + let exec_gas = self.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + self.cfg().fee(ActionCosts::create_account).exec_fee(); + let send_gas = self.cfg().fee(ActionCosts::new_action_receipt).send_fee(false) + + self.cfg().fee(ActionCosts::create_account).send_fee(false) + + self.cfg().fee(ActionCosts::transfer).send_fee(false) + + self.cfg().fee(ActionCosts::add_full_access_key).send_fee(false); self.gas_to_balance(exec_gas + send_gas) } pub fn deploy_contract_cost(&self, num_bytes: u64) -> Balance { - let exec_gas = self.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + self.cfg.fee(ActionCosts::deploy_contract_base).exec_fee() - + num_bytes * self.cfg.fee(ActionCosts::deploy_contract_byte).exec_fee(); - let send_gas = self.cfg.fee(ActionCosts::new_action_receipt).send_fee(true) - + self.cfg.fee(ActionCosts::deploy_contract_base).send_fee(true) - + num_bytes * self.cfg.fee(ActionCosts::deploy_contract_byte).send_fee(true); + let exec_gas = self.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + self.cfg().fee(ActionCosts::deploy_contract_base).exec_fee() + + num_bytes * self.cfg().fee(ActionCosts::deploy_contract_byte).exec_fee(); + let send_gas = self.cfg().fee(ActionCosts::new_action_receipt).send_fee(true) + + self.cfg().fee(ActionCosts::deploy_contract_base).send_fee(true) + + num_bytes * self.cfg().fee(ActionCosts::deploy_contract_byte).send_fee(true); self.gas_to_balance(exec_gas + send_gas) } pub fn function_call_exec_gas(&self, num_bytes: u64) -> Gas { - self.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + self.cfg.fee(ActionCosts::function_call_base).exec_fee() - + num_bytes * self.cfg.fee(ActionCosts::function_call_byte).exec_fee() + self.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + self.cfg().fee(ActionCosts::function_call_base).exec_fee() + + num_bytes * self.cfg().fee(ActionCosts::function_call_byte).exec_fee() } pub fn function_call_cost(&self, num_bytes: u64, prepaid_gas: u64) -> Balance { let exec_gas = self.function_call_exec_gas(num_bytes); - let send_gas = self.cfg.fee(ActionCosts::new_action_receipt).send_fee(false) - + self.cfg.fee(ActionCosts::function_call_base).send_fee(false) - + num_bytes * self.cfg.fee(ActionCosts::function_call_byte).send_fee(false); + let send_gas = self.cfg().fee(ActionCosts::new_action_receipt).send_fee(false) + + self.cfg().fee(ActionCosts::function_call_base).send_fee(false) + + num_bytes * self.cfg().fee(ActionCosts::function_call_byte).send_fee(false); self.gas_to_balance(exec_gas + send_gas + prepaid_gas) } pub fn transfer_fee(&self) -> Gas { - let exec_gas = self.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + self.cfg.fee(ActionCosts::transfer).exec_fee(); - let send_gas = self.cfg.fee(ActionCosts::new_action_receipt).send_fee(false) - + self.cfg.fee(ActionCosts::transfer).send_fee(false); + let exec_gas = self.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + self.cfg().fee(ActionCosts::transfer).exec_fee(); + let send_gas = self.cfg().fee(ActionCosts::new_action_receipt).send_fee(false) + + self.cfg().fee(ActionCosts::transfer).send_fee(false); exec_gas + send_gas } @@ -119,44 +124,44 @@ impl FeeHelper { } pub fn stake_cost(&self) -> Balance { - let exec_gas = self.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + self.cfg.fee(ActionCosts::stake).exec_fee(); - let send_gas = self.cfg.fee(ActionCosts::new_action_receipt).send_fee(true) - + self.cfg.fee(ActionCosts::stake).send_fee(true); + let exec_gas = self.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + self.cfg().fee(ActionCosts::stake).exec_fee(); + let send_gas = self.cfg().fee(ActionCosts::new_action_receipt).send_fee(true) + + self.cfg().fee(ActionCosts::stake).send_fee(true); self.gas_to_balance(exec_gas + send_gas) } pub fn add_key_cost(&self, num_bytes: u64) -> Balance { - let exec_gas = self.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + self.cfg.fee(ActionCosts::add_function_call_key_base).exec_fee() - + num_bytes * self.cfg.fee(ActionCosts::add_function_call_key_byte).exec_fee(); - let send_gas = self.cfg.fee(ActionCosts::new_action_receipt).send_fee(true) - + self.cfg.fee(ActionCosts::add_function_call_key_base).send_fee(true) - + num_bytes * self.cfg.fee(ActionCosts::add_function_call_key_byte).send_fee(true); + let exec_gas = self.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + self.cfg().fee(ActionCosts::add_function_call_key_base).exec_fee() + + num_bytes * self.cfg().fee(ActionCosts::add_function_call_key_byte).exec_fee(); + let send_gas = self.cfg().fee(ActionCosts::new_action_receipt).send_fee(true) + + self.cfg().fee(ActionCosts::add_function_call_key_base).send_fee(true) + + num_bytes * self.cfg().fee(ActionCosts::add_function_call_key_byte).send_fee(true); self.gas_to_balance(exec_gas + send_gas) } pub fn add_key_full_cost(&self) -> Balance { - let exec_gas = self.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + self.cfg.fee(ActionCosts::add_full_access_key).exec_fee(); - let send_gas = self.cfg.fee(ActionCosts::new_action_receipt).send_fee(true) - + self.cfg.fee(ActionCosts::add_full_access_key).send_fee(true); + let exec_gas = self.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + self.cfg().fee(ActionCosts::add_full_access_key).exec_fee(); + let send_gas = self.cfg().fee(ActionCosts::new_action_receipt).send_fee(true) + + self.cfg().fee(ActionCosts::add_full_access_key).send_fee(true); self.gas_to_balance(exec_gas + send_gas) } pub fn delete_key_cost(&self) -> Balance { - let exec_gas = self.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + self.cfg.fee(ActionCosts::delete_key).exec_fee(); - let send_gas = self.cfg.fee(ActionCosts::new_action_receipt).send_fee(true) - + self.cfg.fee(ActionCosts::delete_key).send_fee(true); + let exec_gas = self.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + self.cfg().fee(ActionCosts::delete_key).exec_fee(); + let send_gas = self.cfg().fee(ActionCosts::new_action_receipt).send_fee(true) + + self.cfg().fee(ActionCosts::delete_key).send_fee(true); self.gas_to_balance(exec_gas + send_gas) } pub fn prepaid_delete_account_cost(&self) -> Balance { - let exec_gas = self.cfg.fee(ActionCosts::new_action_receipt).exec_fee() - + self.cfg.fee(ActionCosts::delete_account).exec_fee(); - let send_gas = self.cfg.fee(ActionCosts::new_action_receipt).send_fee(false) - + self.cfg.fee(ActionCosts::delete_account).send_fee(false); + let exec_gas = self.cfg().fee(ActionCosts::new_action_receipt).exec_fee() + + self.cfg().fee(ActionCosts::delete_account).exec_fee(); + let send_gas = self.cfg().fee(ActionCosts::new_action_receipt).send_fee(false) + + self.cfg().fee(ActionCosts::delete_account).send_fee(false); let total_fee = exec_gas + send_gas; @@ -172,13 +177,13 @@ impl FeeHelper { pub fn meta_tx_overhead_cost(&self, actions: &[Action], receiver: &AccountId) -> Balance { // for tests, we assume sender != receiver let sir = false; - let base = self.cfg.fee(ActionCosts::delegate); - let receipt = self.cfg.fee(ActionCosts::new_action_receipt); + let base = self.cfg().fee(ActionCosts::delegate); + let receipt = self.cfg().fee(ActionCosts::new_action_receipt); let total_gas = base.exec_fee() + base.send_fee(sir) + receipt.send_fee(sir) + node_runtime::config::total_send_fees( - &self.cfg, + &self.rt_cfg, sir, actions, receiver,