Transaction Gas Pricing
Overview
This document attempts to serve as the basis for the Transactions pricing formulas for the first Mainnet.
Goals and Motivation
Every finished Transaction carries a price (i.e., Gas costs) regardless of whether it succeeded or failed.
Transactions of different kinds should be priced accordingly. Also, the pricing rules form part of the consensus.
High-level design
Each Transaction price will have both expected and actual costs (in case it was picked to execute).
The Transaction Selection could consider the expected costs, of course.
For Transactions of Fixed-Gas Wasm Templates, the actual costs will always equal the expected costs.
(see also the SVM Gas-Metering SMIP).
Deploy
For the first Mainnet, we’ll end up having only the Genesis Templates, so we probably can skip this kind of Transaction for now.
Here is a proposal for the future - as described at AA Transactions & SVM Integration SMIP, a Template is a collection of Sections.
A naive solution would be giving each byte of the Transaction the same significance and consequently the same price.
A more involved pricing method could price each Section differently. For example, we could price higher the Code Section (containing the Wasm) to incentivize Templates to include less code.
Important: There are no assumptions regarding the order of the Sections.
+----------------+
| |
| Code Section |
| |
+----------------+
| |
| Data Section |
| |
+----------------+
| |
| Ctors Section |
| |
+----------------+
| |
| Header Section | (Optional)
| |
+----------------+
| |
| Schema Section | (Optional)
| |
+----------------+
| |
| API Section | (Optional)
| |
+----------------+
| |
| Deploy Section | (Optional, will be derived from the `Transaction Envelope` and `Transaction Context`)
| |
+----------------+
Spawn
Pricing a Spawn Transaction should differ whether it’s a Self Spawn or a Non-Self Spawn.
When we deal with a Non-Self Spawn, we create a new Account from scratch, while in the Self Spawn case, we’re only filling in the missing details of a Pending Account.
With the current design, there is only one missing part to Activate the Pending Account and its Template Address associated with it. The Immutable Storage should be priced regardless of whether we have a Self Spawn case or not.
So when we Self Spawn a new Account - we price the creation of a Pending Account via the svm_account_create host function (see this SVM issue). That svm_account_create has been priced earlier as part of Call Transaction executing.
Later, we should price the Activation Price, i.e., pricing the missing parts (Template Address for now, maybe we’ll have more parts to fill in the future).
Another alternative could be pricing higher the Pending Account creation and redeeming back the extra payment in the future when pricing the Self-Spawn Transaction - by doing that, we could incentivize completing the Self Spawn flow and leaving less Account remaining in a pending state.
The Immutable Storage initialization (see the SVM Immutable Storage SMIP) should be priced as a one-time operation.
As detailed at the Extend the AccountStorage to support Immutable Storage SVM issue - it suggests taking the immutable_data field given to the Spawn Transaction and persisting it as a single key under the storage backing the Global State.
For the other fields (besides the immutable_data) of the Transaction, we can decide to price each one differently or not.
The remaining part is the ctor to run (using the Fixed-Gas Wasm or the future Gas Metering).
Last note, the verify (and maybe the future authorize if we’ll have that) methods should have a MAX_VERIFY_GAS enforced. Right now, we only deal with the Fixed-Gas Wasm code, so we can know without running any code whether the verify exceeds the MAX_VERIFY_GAS or not.
For the Fixed-Gas Wasm, that validation should be part of the Deploy.
That said, for future Non-Fixed Gas Wasm, we’ll require to use Gas Metering when running verify.
However, we could specialize the verify functions such that Templates non-compliant with the Fixed-Gas Wasm restrictions will have to enforce only the verify function to be Fixed-Gas Wasm compliant - seems like a fair trade-off. If that path is taken, we could validate upon Deploy Template that the verify is within the MAX_VERIFY_GAS limit even though any other Template function might be Non-Fixed Gas Wasm.
Also, the verify running should be associated with the Principal Template (or the template_address field of the Spawn Transaction when we talk about a Self-Spawn case).
Call
Pricing a Call transaction will involve pricing the Transaction payload. Therefore, there is no unique field as the immutable_data of the Spawn Transaction.
Additionally, the function to run should be priced using the exact mechanism as in the ctor of the Spawn Transaction.
Similarly, we need to enforce the Gas of the running verify is within the MAX_VERIFY_GAS limits.
Questions/concerns
TBD
Stakeholders and reviewers
@neysofu
@avive
@moshababo
@lrettig
@noamnelke
Transaction Gas Pricing
Overview
This document attempts to serve as the basis for the
Transactionspricing formulas for the first Mainnet.Goals and Motivation
Every finished
Transactioncarries a price (i.e.,Gascosts) regardless of whether it succeeded or failed.Transactions of different kinds should be priced accordingly. Also, the pricing rules form part of the consensus.
High-level design
Each
Transactionprice will have both expected and actual costs (in case it was picked to execute).The
Transaction Selectioncould consider the expected costs, of course.For
TransactionsofFixed-Gas Wasm Templates, the actual costs will always equal the expected costs.(see also the
SVM Gas-Metering SMIP).Deploy
For the first Mainnet, we’ll end up having only the
Genesis Templates, so we probably can skip this kind ofTransactionfor now.Here is a proposal for the future - as described at
AA Transactions & SVM Integration SMIP, aTemplateis a collection of Sections.A naive solution would be giving each byte of the
Transactionthe same significance and consequently the same price.A more involved pricing method could price each
Sectiondifferently. For example, we could price higher theCode Section(containing the Wasm) to incentivizeTemplatesto include less code.Spawn
Pricing a
Spawn Transactionshould differ whether it’s aSelf Spawnor aNon-Self Spawn.When we deal with a
Non-Self Spawn, we create a newAccountfrom scratch, while in theSelf Spawncase, we’re only filling in the missing details of aPending Account.With the current design, there is only one missing part to
ActivatethePending Accountand itsTemplate Addressassociated with it. TheImmutable Storageshould be priced regardless of whether we have aSelf Spawncase or not.So when we
Self Spawna newAccount- we price the creation of aPending Accountvia thesvm_account_createhost function (see this SVM issue). Thatsvm_account_createhas been priced earlier as part ofCall Transactionexecuting.Later, we should price the
Activation Price, i.e., pricing the missing parts (Template Addressfor now, maybe we’ll have more parts to fill in the future).Another alternative could be pricing higher the
Pending Accountcreation and redeeming back the extra payment in the future when pricing theSelf-Spawn Transaction- by doing that, we could incentivize completing theSelf Spawnflow and leaving lessAccountremaining in a pending state.The
Immutable Storageinitialization (see theSVM Immutable StorageSMIP) should be priced as a one-time operation.As detailed at the Extend the AccountStorage to support Immutable Storage SVM issue - it suggests taking the
immutable_datafield given to theSpawn Transactionand persisting it as a single key under the storage backing theGlobal State.For the other fields (besides the
immutable_data) of the Transaction, we can decide to price each one differently or not.The remaining part is the
ctorto run (using theFixed-Gas Wasmor the futureGas Metering).Last note, the
verify(and maybe the futureauthorizeif we’ll have that) methods should have aMAX_VERIFY_GASenforced. Right now, we only deal with theFixed-Gas Wasmcode, so we can know without running any code whether theverifyexceeds theMAX_VERIFY_GASor not.For the
Fixed-Gas Wasm, that validation should be part of theDeploy.That said, for future
Non-Fixed Gas Wasm, we’ll require to useGas Meteringwhen runningverify.However, we could specialize the
verifyfunctions such thatTemplatesnon-compliant with theFixed-Gas Wasmrestrictions will have to enforce only theverifyfunction to beFixed-Gas Wasmcompliant - seems like a fair trade-off. If that path is taken, we could validate uponDeploy Templatethat theverifyis within theMAX_VERIFY_GASlimit even though any otherTemplatefunction might beNon-Fixed Gas Wasm.Also, the
verifyrunning should be associated with thePrincipal Template(or thetemplate_addressfield of theSpawn Transactionwhen we talk about aSelf-Spawncase).Call
Pricing a
Calltransaction will involve pricing theTransactionpayload. Therefore, there is no unique field as theimmutable_dataof theSpawn Transaction.Additionally, the function to run should be priced using the exact mechanism as in the
ctorof theSpawn Transaction.Similarly, we need to enforce the
Gasof the runningverifyis within theMAX_VERIFY_GASlimits.Questions/concerns
TBD
Stakeholders and reviewers
@neysofu
@avive
@moshababo
@lrettig
@noamnelke