spacemeshos / SMIPS

Spacemesh Improvement Proposals
https://spacemesh.io
Creative Commons Zero v1.0 Universal
7 stars 1 forks source link

Transaction Gas Pricing #83

Closed YaronWittenstein closed 1 year ago

YaronWittenstein commented 2 years ago

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

lrettig commented 1 year ago

Closing for now as outdated