diff --git a/docs/rfc/rfc-011-delete-gas.md b/docs/rfc/rfc-011-delete-gas.md new file mode 100644 index 000000000..e53084733 --- /dev/null +++ b/docs/rfc/rfc-011-delete-gas.md @@ -0,0 +1,140 @@ +# RFC 011: Remove Gas From Tendermint + +## Changelog + +- 03-Feb-2022: Initial draft (@williambanfield). + +## Abstract + +In the v0.25.0 release, Tendermint added a mechanism for tracking 'Gas' in the mempool. +At a high level, Gas allows applications to specify how much it will cost the network, +often in compute resources, to execute a given transaction. While such a mechanism is common +in blockchain applications, it is not generalizable enough to be a maintained as a part +of Tendermint. This RFC explores the possibility of removing the concept of Gas from +Tendermint while still allowing applications the power to control the contents of +blocks to achieve similar goals. + +## Background + +The notion of Gas was included in the original Ethereum whitepaper and exists as +an important feature of the Ethereum blockchain. + +The [whitepaper describes Gas][eth-whitepaper-messages] as an Anti-DoS mechanism. The Ethereum Virtual Machine +provides a Turing complete execution platform. Without any limitations, malicious +actors could waste computation resources by directing the EVM to perform large +or even infinite computations. Gas serves as a metering mechanism to prevent this. + +Gas appears to have been added to Tendermint multiple times, initially as part of +a now defunct `/vm` package, and in its most recent iteration [as part of v0.25.0][gas-add-pr] +as a mechanism to limit the transactions that will be included in the block by an additional +parameter. + +Gas has gained adoption within the Cosmos ecosystem [as part of the Cosmos SDK][cosmos-sdk-gas]. +The SDK provides facilities for tracking how much 'Gas' a transaction is expected to take +and a mechanism for tracking how much gas a transaction has already taken. + +Non-SDK applications also make use of the concept of Gas. Anoma appears to implement +[a gas system][anoma-gas] to meter the transactions it executes. + +While the notion of gas is present in projects that make use of Tendermint, it is +not a concern of Tendermint's. Tendermint's value and goal is producing blocks +via a distributed consensus algorithm. Tendermint relies on the application specific +code to decide how to handle the transactions Tendermint has produced (or if the +application wants to consider them at all). Gas is an application concern. + +Our implementation of Gas is causing issues for node operators and relayers. At +the moment, transactions that overflow the configured 'MaxGas' can be silently rejected +from the mempool. Overflowing MaxGas is the _only_ way that a transaction can be considered +invalid that is not directly a result of failing the `CheckTx`. Operators, and the application, +do not know that a transaction was removed from the mempool for this reason. A stateless check +of this nature is exactly what `CheckTx` exists for and there is no reason for the mempool +to keep track of this data separately. + +Removing Gas from Tendermint and the mempool would allow for the 'mempool' to be a better +abstraction: any transaction that arrived at `CheckTx` and passed the check will either be +a candidate for a later block or evicted after a TTL is reached. All other transactions are +completely invalid and can be discarded forever. + +Removing gas will not be completely straightforward. It will mean ensuring that +equivalent functionality can be implemented outside of the mempool using the mempool's API. + +## Discussion + +This section catalogs the functionality that will need to exist within the Tendermint +mempool to allow Gas to be removed and replaced by application-side bookkeeping. + +### Requirement: Provide Mempool Tx Sorting Mechanism + +Gas produces a market for inclusion in a block. On many networks, a [gas fee][cosmos-sdk-fees] is +included in pending transactions. This fee indicates how much a user is willing to +pay per unit of execution and the fees are distributed to validators. + +Validators wishing to extract higher gas fees are incentivized to include transactions +with the highest listed gas fees into each block. This produces a naturally ordering +of the pending transactions. Applications wishing to implement a gas mechanism need +to be able to order the transactions in the mempool. This can trivially be accomplished +by sorting transactions using the `priority` field available to applications as part of +v0.35's `ResponseCheckTx` message. + +### Requirement: Allow Application-Defined Block Resizing + +When creating a block proposal, Tendermint pulls a set of possible transactions out of +the mempool to include in the next block. Tendermint uses MaxGas to limit the set of transactions +it pulls out of the mempool fetching a set of transactions whose sum is less than MaxGas. + +By removing gas tracking from Tendermint's mempool, Tendermint will need to provide a way for +applications to determine an acceptable set of transactions to include in the block. + +This is what the new ABCI++ `PrepareProposal` method is useful for. Applications +that wish to limit the contents of a block by an application-defined limit may +do so by removing transactions from the proposal it is passed during `PrepareProposal`. + +Fully meeting the requirements of the current Gas system would mean adding functionality that is +not currently provided the `PrepareProposal` method. +Applications that wish to include _more_ transactions in the proposal than `PrepareProposal` +initially passed to it cannot do so in the current design. [Issue 7750][issue-7750] has been filed to discuss +and possibly solve for this. + +### Requirement: Handle Transaction Metadata + +Moving the gas mechanism into applications adds an additional piece of complexity +to applications. The application must now track how much gas it expects a transaction +to consume. The mempool currently handles this bookkeeping responsibility and uses the estimated +gas to determine the set of transactions to include in the block. In order to task +the application with keeping track of this metadata, we should make it easier for the +application to do so. In general, we'll want to keep only one copy of this type +of metadata in the program at a time, either in the application or in Tendermint. + +The following sections are possible solutions to the problem of storing transaction +metadata without duplication. + +#### Metadata Handling: EvictTx Callback + +A possible approach to handling transaction metadata is by adding a new `EvictTx` +ABCI method. Whenever the mempool is removing a transaction, either because it has +reached its TTL or because it failed `RecheckTx`, `EvictTx` would be called with +the transaction hash. This would indicate to the application that it could free any +metadata it was storing about the transaction such as the computed gas fee. + +Eviction callbacks are pretty common in caching systems, so this would be very +well-worn territory. + +#### Metadata Handling: Application-Specific Metadata Field(s) + +An alternative approach to handling transaction metadata would be would be the +addition of a new application-metadata field in the `ResponseCheckTx`. This field +would be a protocol buffer message whose contents were entirely opaque to Tendermint. +The application would be responsible for marshalling and unmarshalling whatever data +it stored in this field. During `PrepareProposal`, the application would be passed +this metadata along with the transaction, allowing the application to use it to perform +any necessary filtering. + +## References + +[eth-whitepaper-messages]: https://ethereum.org/en/whitepaper/#messages-and-transactions +[gas-add-pr]: https://github.com/tendermint/tendermint/pull/2360 +[cosmos-sdk-gas]: https://github.com/cosmos/cosmos-sdk/blob/c00cedb1427240a730d6eb2be6f7cb01f43869d3/docs/basics/gas-fees.md +[cosmos-sdk-fees]: https://github.com/cosmos/cosmos-sdk/blob/c00cedb1427240a730d6eb2be6f7cb01f43869d3/docs/basics/tx-lifecycle.md#gas-and-fees +[anoma-gas]: https://github.com/anoma/anoma/blob/6974fe1532a59db3574fc02e7f7e65d1216c1eb2/docs/src/specs/ledger.md#transaction-execution +[cosmos-sdk-fee]: https://github.com/cosmos/cosmos-sdk/blob/c00cedb1427240a730d6eb2be6f7cb01f43869d3/types/tx/tx.pb.go#L780-L794 +[issue-7750]: https://github.com/tendermint/tendermint/issues/7750