NEPs icon indicating copy to clipboard operation
NEPs copied to clipboard

Proposal: Fee upgrade process

Open evgenykuzyakov opened this issue 4 years ago • 5 comments

Fee upgrade process

This doc explains the process of upgrading Runtime fees in nearcore.

Background

We've decided to upgrade contracts compilation cache from fully in-memory cache to a on-disk cache. The on-disk cache allows to store all contracts pre-compiled and removes the hot/cold cache compilation issue. This is due to being able to compile contracts when the code is first deployed.

Changes

  • Move contract compilation fee from FunctionCallAction to DeployContractAction. Since the size of the contract is known for the DeployContractAction, the full cost can be deducted at the moment this action is created and doesn't need to come from the attached gas at the runtime. This decreases the cost of a function call and makes it predictable. At the same time it makes the deployment action more expensive, but it has to be paid only once.
  • We've re-estimated Runtime fees by subtracting the cost of the base actions. E.g. function call base cost doesn't include the cost of the action receipt and the cost of the contract compilation. This dramatically decreases the base action costs, as well as VM costs. So we need to update runtime fees.
  • Runtime param fee estimator is based on the number of CPU instructions, so some disk blocking actions might not be accounted for. We'll estimate the overhead of disk vs RAM and include this coefficient for all metrics.
  • ActionReceipt cost comes from the account lookup in a trie. So if the receiver is different from signer, this creates 2 lookups in a trie, which more expensive than a local receipt. But since a local receipt can't be created from another receipt (it can only be created directly form SignedTransaction), the SIR (Sender is Receiver) cost should be the same as non-sir. The param estimator only uses SIR action for computing base of the actions.

Current Protocol Upgrade

  • [ ] Estimate disk vs RAM overhead of param estimator. Compute a coefficient to add disk overhead safety.
  • [ ] Remove runtime contract compilation cost from the function call. Set it to 0 in the fees.
  • [ ] Increase deploy_contract_cost and deploy_contract_cost_per_byte fees by the estimated compilation cost.
  • [ ] Add a new initialization method to RuntimeConfig that is based on the protocol version.
  • [ ] Change Default implementation to use PROTOCOL_VERSION and the new method.
  • [ ] Add protocol_version to Runtime internal state.
  • [ ] Upgrade config within Runtime when the apply_state.current_protocol_version is different from the self.protocol_version.
  • [ ] Make config record private and expose get_config() method that takes protocol version. This will resolve validate_tx protocol issues.

NOTE: Main concern here is RuntimeConfig::free() options that might come in genesis that are different from the default values for a current protocol version

evgenykuzyakov avatar Oct 05 '20 21:10 evgenykuzyakov

But since a local receipt can't be created from another receipt, the SIR (Sender is Receiver) cost should be the same as non-sir.

Don't quite follow here. You said that in the non-sir case there are two lookups which is more expensive, but here you said it doesn't matter. Why?

bowenwang1996 avatar Oct 05 '20 23:10 bowenwang1996

Don't quite follow here. You said that in the non-sir case there are two lookups which is more expensive, but here you said it doesn't matter. Why?

Clarified:

But since a local receipt can't be created from another receipt (it can only be created directly form SignedTransaction), the SIR (Sender is Receiver) cost should be the same as non-sir.

evgenykuzyakov avatar Oct 06 '20 00:10 evgenykuzyakov

@evgenykuzyakov I still don't fully understand. When you create a receipt, couldn't predecessor_id be the same as receiver_id? This has nothing to do with local receipt.

bowenwang1996 avatar Oct 06 '20 03:10 bowenwang1996

I still don't fully understand. When you create a receipt, couldn't predecessor_id be the same as receiver_id? This has nothing to do with local receipt.

Yes it can. While the fees are going to use send_sir, the actual execution will not happen until the next block, which makes it as expensive as a receipt which has a different receiver_id. So we shouldn't make send_sir cheaper than send_not_sir until we address the cost concerns.

evgenykuzyakov avatar Oct 06 '20 23:10 evgenykuzyakov

To make sure we don't lose track of things, this is where the new costs are computed https://github.com/near/nearcore/pull/3279. Data receipt creation cost will be reduced from 4.7Tgas to 0.03Tgas once we upgrade the fees.

bowenwang1996 avatar Jun 10 '21 23:06 bowenwang1996