Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Fee upgrade process #120

Open
8 tasks
evgenykuzyakov opened this issue Oct 5, 2020 · 5 comments
Open
8 tasks

Proposal: Fee upgrade process #120

evgenykuzyakov opened this issue Oct 5, 2020 · 5 comments
Assignees

Comments

@evgenykuzyakov
Copy link
Contributor

evgenykuzyakov commented Oct 5, 2020

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

@bowenwang1996
Copy link
Collaborator

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?

@evgenykuzyakov
Copy link
Contributor Author

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.

@bowenwang1996
Copy link
Collaborator

@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.

@evgenykuzyakov
Copy link
Contributor Author

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 pushed a commit to near/nearcore that referenced this issue Oct 12, 2020
Move `RuntimeConfig` from `Runtime` initialization to `ApplyState` object.
This makes `Runtime` completely stateless and allows to execute transitions based on different configs.
It allows to upgrade `RuntimeConfig` with the new fees based on the protocol version for the current block.

This change should be NOOP and doesn't change the protocol. 

NEP: near/NEPs#120
Issue: #3158

# Test plan:

- [X] CI
- [x] http://nayduck.eastus.cloudapp.azure.com:3000/#/run/553
olonho pushed a commit to near/nearcore that referenced this issue Oct 15, 2020
Move `RuntimeConfig` from `Runtime` initialization to `ApplyState` object.
This makes `Runtime` completely stateless and allows to execute transitions based on different configs.
It allows to upgrade `RuntimeConfig` with the new fees based on the protocol version for the current block.

This change should be NOOP and doesn't change the protocol. 

NEP: near/NEPs#120
Issue: #3158

# Test plan:

- [X] CI
- [x] http://nayduck.eastus.cloudapp.azure.com:3000/#/run/553
olonho pushed a commit to near/nearcore that referenced this issue Oct 19, 2020
Move `RuntimeConfig` from `Runtime` initialization to `ApplyState` object.
This makes `Runtime` completely stateless and allows to execute transitions based on different configs.
It allows to upgrade `RuntimeConfig` with the new fees based on the protocol version for the current block.

This change should be NOOP and doesn't change the protocol. 

NEP: near/NEPs#120
Issue: #3158

# Test plan:

- [X] CI
- [x] http://nayduck.eastus.cloudapp.azure.com:3000/#/run/553
chefsale pushed a commit to near/nearcore that referenced this issue Oct 19, 2020
Move `RuntimeConfig` from `Runtime` initialization to `ApplyState` object.
This makes `Runtime` completely stateless and allows to execute transitions based on different configs.
It allows to upgrade `RuntimeConfig` with the new fees based on the protocol version for the current block.

This change should be NOOP and doesn't change the protocol. 

NEP: near/NEPs#120
Issue: #3158

# Test plan:

- [X] CI
- [x] http://nayduck.eastus.cloudapp.azure.com:3000/#/run/553
@bowenwang1996
Copy link
Collaborator

bowenwang1996 commented Jun 10, 2021

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants