diff --git a/FIPS/fip-0032.md b/FIPS/fip-0032.md new file mode 100644 index 000000000..0526df6dc --- /dev/null +++ b/FIPS/fip-0032.md @@ -0,0 +1,267 @@ +--- +fip: "0032" +title: Gas model adjustment for non-programmable FVM +author: Raúl Kripalani (@raulkr), Steven Allen (@stebalien) +discussions-to: https://github.com/filecoin-project/FIPs/discussions/316 +status: Draft +type: Technical +category: Core +created: 2022-03-08 +spec-sections: + - TBD +requires: + - FIP-0030 + - FIP-0031 +replaces: N/A +--- + +# FIP-0032: Gas model adjustment for non-programmable FVM + +## Simple Summary + +This FIP is part of a two-FIP series that adjust the gas model of the Filecoin +blockchain in preparation of user-programmable actors. This FIP focuses on +attaining high-fidelity gas accounting under the Wasm runtime that built-in +system actors will migrate to as part of FIP-0030 and FIP-0031. It does not +cover upcoming system features like actor deployment, actor loading, memory +management, and more. Those will be addressed in a subsequent FIP that focuses +on gas model changes to support user-programmability. + +## Abstract + +With the arrival of the Filecoin Virtual Machine, the Filecoin network will gain +the capability to run untrusted code in the form of user-defined actors. +However, the current gas model is designed strictly for predefined, trusted +code. In order to maintain network security guarantees, the gas model needs to +evolve to accurately charge for computational instructions and resource usage of +actor logic. + +This FIP expands the current gas model by introducing a new gas category to +account for the real compute cost of the logic performed by every actor in the +system. It also rearchitects IPLD state management gas, and adjusts the actor +call fee to account for Wasm invocation container mechanics. + +This is the first FIP out of a two-FIP series to revise the gas model as a +result of the introduction of the Filecoin Virtual Machine in FIP-0030 and +FIP-0031. This FIP should accompany those FIPs under the same network upgrade. + +## Change Motivation + +Gas is an essential mechanism to (a) compensate the network for the computation +performed during transaction execution, and to (b) restrict the compute capacity +of blocks to achieve a designated epoch time (30 seconds). + +Today, Filecoin determines the amount of gas a transaction consumes by +intercepting specific operations and actions, and applying gas explicit gas +charges on them. Concretely: + +- On including a chain message, variable on the length of the message. +- On returning a value, variable on the length of returned payload. +- On performing a call, dependent on the type of call (simple value transfer, or + other). +- On performing an IPLD store get, fixed amount. +- On performing an IPLD store put, variable on block payload size. +- On actor creation, fixed amount. +- On actor deletion, fixed amount. +- On cryptographic operations: + - On signature verification, variable on signature type and plaintext + length. + - On hashing, fixed price. + - On computing the CID of an unsealed sector, variable on proof type and + piece characteristics. + - On verifying a seal, variable on the seal characteristics. + - On verifying a window PoSt, variable on the PoSt characteristics. + - On verifying a consensus fault. + +None of these gas charges accounts for the costs of the execution of the actor’s +compute logic itself. This results in an incomplete resource accounting model. +So far, the network has coped without it because: + +1. The cost of built-in actor logic is negligible when compared to the cost of + the above operations, most of which are triggered through syscalls. +2. Only pre-determined, trusted logic runs on chain in the form of built-in + actors. +3. Technical limitations. Prior to the FVM (FIP-0030, FIP-0031), there was no + portable actor bytecode whose execution could be metered identically across + all implementations. + +With the ability to deploy user-defined actors on the FVM, these assumptions no +longer stand and it becomes important to start tracking real execution costs +with the highest fidelity possible, to preserve security guarantees, and to +compensate the network for the logic it executes. + +## Specification + +Here’s an overview of proposed changes to the existing gas model. We explain +each one in detail in the following sections. + +- Introduce Wasm bytecode-metered execution gas. +- Adjust the *actor call* fee, to account for new call dispatch overhead. +- Rearchitect the IPLD state IO fees. + +### Wasm bytecode-metered execution gas + +We introduce a new category of gas. Execution gas is charged per Wasm +instruction. Every Wasm instruction has a predefined amount of execution units +associated with it. + +Every Wasm instruction expends a flat 1 execution unit, except the following +structural Wasm instructions: `nop`, `drop`, `block`, `loop`, `unreachable`, +`return`, `else` and `end` . These instructions expend 0 execution units +because either they do not translate into machine instructions by themselves, or +they are control flow instructions with no logic to evaluate. + +**Pricing formula** + +The conversion of Wasm execution units to Filecoin gas units is at a predefined +ratio of `<>`. This equivalence has been +calculated by performing extensive benchmarks, with the goal of honouring the +invariant baseline target of 10 gas units/ns of wall clock time[^1]. + +Both the pricing policy for Wasm instructions and the conversion rate need to be +assessed and revised continuously as technology improves (e.g. Wasm compilers +and processors). The ongoing goal is to sustain high execution fidelity. + +### Call gas fee + +In Filecoin network version 15 and earlier, the call gas fee is higher for value +transfers than it is for actor code invocations. This may sound +counterintuitive, but it follows the fact that the call fee has to cover the +full validation and state update cost of the transaction, because these +transactions don’t invoke actor code. Conversely, the call fee for an actor +invocation represents only the dispatch effort, hence why it’s lower. + +With FVM actors, the call cost structure changes. For actor code invocations, a +Wasm-based invocation container needs to be instantiated, and parameters need to +be serialized and inserted into the IPLD blockstore. In other words, there is +more work to do that than previously, and therefore the fee is adjusted upward. + +**Pricing formula** + +``` +TODO: benchmarking +``` + +### IPLD state management fees + +Currently, IPLD block read incur a fixed fee, and IPLD block writes incur a +variable fee, dependent on the number of bytes written. + +With the FVM, IPLD state I/O is managed through five syscalls, with the +specified overhead and pricing: + +- `block_open`: looks up the supplied CID, loads the block from the state + blockstore into the FVM kernel’s block cache, reports its size and codec. It + returns a numeric block handle. + - Overhead: This syscall traverses the FVM<>client boundary via an extern in + order to query the state blockstore. This leads to disk IO with associated + read amplification. The bytes returned through the extern are copied into + the FVM’s memory so that the buffer can be reclaimed by the client side; + thus there is an alloc and memcpy cost. The bytes are retained in memory + until the actor call finishes and the invocation container is dropped, and + thus the actor is charged for this memory usage. + - Cost: `<>`. +- `block_read`: takes a block handle and an output buffer, and copies the + block’s data from the FVM kernel’s block cache into the actor’s memory. + - Overhead: This syscall resolves inside the FVM and doesn’t traverse the + FVM<>node boundary. The overhead is that of a memcpy operation. + - Cost: `<>`. +- `block_write`: takes some block data and a codec, and merely copies it to the + FVM kernel’s block cache. It returns a numeric block handle. + - Overhead: This syscall resolves inside the FVM and doesn’t traverse the + FVM<>node boundary. It involves a memcpy to a buffer that is retained + until the actor call finishes. The bytes are retained in memory until the + actor call finishes and the invocation container is dropped, and thus the + actor is charged for this memory usage. + - Cost: `<>`. +- `block_link`: computes the CID of a block, and commits the block to the state + blockstore. + - Overhead: This syscall traverses the FVM<>client boundary via an extern in + order to write to the state blockstore (although this is deferred until + the machine flush). This leads to disk IO with associated write + amplification. The bytes are copied over to the client’s memory, thus + there is an alloc and memcpy cost. Computing the CID involves a hashing + operation (akin to the hash syscall, but without the syscall overhead). + Because the CID is returned to the actor via an output buffer, there is + another memcpy involved. + - Cost: `<>`. +- `block_stat`: returns the length and the codec of a block. + - Overhead: This syscall resolves inside the FVM and doesn’t traverse the + FVM<>node boundary. It performs a map lookup and returns an integer tuple. + - Cost: `<>`. + +## Design Rationale + +To simplify community discussion and align with the FVM deployment roadmap, all +changes related to new system features related to user-programmable actors are +kept out of scope of this FIP. This set of changes covers only the technological +transition to a Wasm runtime for built-in actors. This FIP will be followed by +another FIP introducing the former. + +Concerning the design of each individual change, the specification section +elaborates on overhead that is being accounted for and the variables that make +up every pricing formula. + +## Backwards Compatibility + +The data model by which gas allowance and usage is represented in external +interfaces (gas limit, gas used, etc.) remains unchanged. However, the same +transaction made before and after this FIP will, with very high likelihood, +result in different values for *gas used*. Transactions sitting in the mempool +at the activation epoch of this FIP will need to be re-estimated and replaced. + +## Test Cases + +Testing for this FIP involves two efforts: + +1. An updated corpus of FVM-compatible [test + vectors](https://github.com/filecoin-project/fvm-test-vectors) with the new + gas model. +2. The testnet plan laid out in FIP-0031. + +## Security Considerations + +TODO draft. + +## Incentive Considerations + +With the introduction of execution gas to account for real execution cost, actor +compute logic will no longer be exempted from gas charges, thus resulting in a +net increase in gas expenditure in the network. + +## Product Considerations + +The cost every actor method changes upwards as a result of this FIP. +Furthermore, by charging for actor logic itself, methods that are more +computationally intensive may have their price structure changed significantly. +These two implications may transpire as changes in onboarding, power maintenance, +deal-making, and other features that are noteworthy from a product perspective. + +`<>.` + +## Implementation + +For clients relying on the reference FVM implementation +([filecoin-project/ref-fvm](https://github.com/filecoin-project/ref-fvm)), the +implementation of this FIP will be transparent, as it is self-contained inside +the FVM. + +## Copyright + +Copyright and related rights waived via +[CC0](https://creativecommons.org/publicdomain/zero/1.0/). + +## Footnotes + +[^1]: The baseline target itself determined by the need to sustain a 30 second + epoch frequency, with a 6 second block propagation time, under these + circumstances, which represent the absolute worst possible scenario: + - Block gas limit of 15B gas units. + - Attaining the maximum winrate at an epoch (11). + - No duplicated messages across blocks in a tipset. + - 100% saturation of every block with compute. + + The choice of 10 gas units/ns as a baseline implies a block validation time + of 1.5s and a fully saturated tipset validation time of 16.5s (given that + message and block execution cannot be parallelized).