github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/docs/rfc/rfc-011-delete-gas.md (about) 1 # RFC 011: Remove Gas From Tendermint 2 3 ## Changelog 4 5 - 03-Feb-2022: Initial draft (@williambanfield). 6 - 10-Feb-2022: Update in response to feedback (@williambanfield). 7 - 11-Feb-2022: Add reflection on MaxGas during consensus (@williambanfield). 8 9 ## Abstract 10 11 In the v0.25.0 release, Tendermint added a mechanism for tracking 'Gas' in the mempool. 12 At a high level, Gas allows applications to specify how much it will cost the network, 13 often in compute resources, to execute a given transaction. While such a mechanism is common 14 in blockchain applications, it is not generalizable enough to be a maintained as a part 15 of Tendermint. This RFC explores the possibility of removing the concept of Gas from 16 Tendermint while still allowing applications the power to control the contents of 17 blocks to achieve similar goals. 18 19 ## Background 20 21 The notion of Gas was included in the original Ethereum whitepaper and exists as 22 an important feature of the Ethereum blockchain. 23 24 The [whitepaper describes Gas][eth-whitepaper-messages] as an Anti-DoS mechanism. The Ethereum Virtual Machine 25 provides a Turing complete execution platform. Without any limitations, malicious 26 actors could waste computation resources by directing the EVM to perform large 27 or even infinite computations. Gas serves as a metering mechanism to prevent this. 28 29 Gas appears to have been added to Tendermint multiple times, initially as part of 30 a now defunct `/vm` package, and in its most recent iteration [as part of v0.25.0][gas-add-pr] 31 as a mechanism to limit the transactions that will be included in the block by an additional 32 parameter. 33 34 Gas has gained adoption within the Cosmos ecosystem [as part of the Cosmos SDK][cosmos-sdk-gas]. 35 The SDK provides facilities for tracking how much 'Gas' a transaction is expected to take 36 and a mechanism for tracking how much gas a transaction has already taken. 37 38 Non-SDK applications also make use of the concept of Gas. Anoma appears to implement 39 [a gas system][anoma-gas] to meter the transactions it executes. 40 41 While the notion of gas is present in projects that make use of Tendermint, it is 42 not a concern of Tendermint's. Tendermint's value and goal is producing blocks 43 via a distributed consensus algorithm. Tendermint relies on the application specific 44 code to decide how to handle the transactions Tendermint has produced (or if the 45 application wants to consider them at all). Gas is an application concern. 46 47 Our implementation of Gas is not currently enforced by consensus. Our current validation check that 48 occurs during block propagation does not verify that the block is under the configured `MaxGas`. 49 Ensuring that the transactions in a proposed block do not exceed `MaxGas` would require 50 input from the application during propagation. The `ProcessProposal` method introduced 51 as part of ABCI++ would enable such input but would further entwine Tendermint and 52 the application. The issue of checking `MaxGas` during block propagation is important 53 because it demonstrates that the feature as it currently exists is not implemented 54 as fully as it perhaps should be. 55 56 Our implementation of Gas is causing issues for node operators and relayers. At 57 the moment, transactions that overflow the configured 'MaxGas' can be silently rejected 58 from the mempool. Overflowing MaxGas is the _only_ way that a transaction can be considered 59 invalid that is not directly a result of failing the `CheckTx`. Operators, and the application, 60 do not know that a transaction was removed from the mempool for this reason. A stateless check 61 of this nature is exactly what `CheckTx` exists for and there is no reason for the mempool 62 to keep track of this data separately. A special [MempoolError][add-mempool-error] field 63 was added in v0.35 to communicate to clients that a transaction failed after `CheckTx`. 64 While this should alleviate the pain for operators wishing to understand if their 65 transaction was included in the mempool, it highlights that the abstraction of 66 what is included in the mempool is not currently well defined. 67 68 Removing Gas from Tendermint and the mempool would allow for the mempool to be a better 69 abstraction: any transaction that arrived at `CheckTx` and passed the check will either be 70 a candidate for a later block or evicted after a TTL is reached or to make room for 71 other, higher priority transactions. All other transactions are completely invalid and can be discarded forever. 72 73 Removing gas will not be completely straightforward. It will mean ensuring that 74 equivalent functionality can be implemented outside of the mempool using the mempool's API. 75 76 ## Discussion 77 78 This section catalogs the functionality that will need to exist within the Tendermint 79 mempool to allow Gas to be removed and replaced by application-side bookkeeping. 80 81 ### Requirement: Provide Mempool Tx Sorting Mechanism 82 83 Gas produces a market for inclusion in a block. On many networks, a [gas fee][cosmos-sdk-fees] is 84 included in pending transactions. This fee indicates how much a user is willing to 85 pay per unit of execution and the fees are distributed to validators. 86 87 Validators wishing to extract higher gas fees are incentivized to include transactions 88 with the highest listed gas fees into each block. This produces a natural ordering 89 of the pending transactions. Applications wishing to implement a gas mechanism need 90 to be able to order the transactions in the mempool. This can trivially be accomplished 91 by sorting transactions using the `priority` field available to applications as part of 92 v0.35's `ResponseCheckTx` message. 93 94 ### Requirement: Allow Application-Defined Block Resizing 95 96 When creating a block proposal, Tendermint pulls a set of possible transactions out of 97 the mempool to include in the next block. Tendermint uses MaxGas to limit the set of transactions 98 it pulls out of the mempool fetching a set of transactions whose sum is less than MaxGas. 99 100 By removing gas tracking from Tendermint's mempool, Tendermint will need to provide a way for 101 applications to determine an acceptable set of transactions to include in the block. 102 103 This is what the new ABCI++ `PrepareProposal` method is useful for. Applications 104 that wish to limit the contents of a block by an application-defined limit may 105 do so by removing transactions from the proposal it is passed during `PrepareProposal`. 106 Applications wishing to reach parity with the current Gas implementation may do 107 so by creating an application-side limit: filtering out transactions from 108 `PrepareProposal` the cause the proposal the exceed the maximum gas. Additionally, 109 applications can currently opt to have all transactions in the mempool delivered 110 during `PrepareProposal` by passing `-1` for `MaxGas` and `MaxBytes` into 111 [ReapMaxBytesMaxGas][reap-max-bytes-max-gas]. 112 113 ### Requirement: Handle Transaction Metadata 114 115 Moving the gas mechanism into applications adds an additional piece of complexity 116 to applications. The application must now track how much gas it expects a transaction 117 to consume. The mempool currently handles this bookkeeping responsibility and uses the estimated 118 gas to determine the set of transactions to include in the block. In order to task 119 the application with keeping track of this metadata, we should make it easier for the 120 application to do so. In general, we'll want to keep only one copy of this type 121 of metadata in the program at a time, either in the application or in Tendermint. 122 123 The following sections are possible solutions to the problem of storing transaction 124 metadata without duplication. 125 126 #### Metadata Handling: EvictTx Callback 127 128 A possible approach to handling transaction metadata is by adding a new `EvictTx` 129 ABCI method. Whenever the mempool is removing a transaction, either because it has 130 reached its TTL or because it failed `RecheckTx`, `EvictTx` would be called with 131 the transaction hash. This would indicate to the application that it could free any 132 metadata it was storing about the transaction such as the computed gas fee. 133 134 Eviction callbacks are pretty common in caching systems, so this would be very 135 well-worn territory. 136 137 #### Metadata Handling: Application-Specific Metadata Field(s) 138 139 An alternative approach to handling transaction metadata would be would be the 140 addition of a new application-metadata field in the `ResponseCheckTx`. This field 141 would be a protocol buffer message whose contents were entirely opaque to Tendermint. 142 The application would be responsible for marshalling and unmarshalling whatever data 143 it stored in this field. During `PrepareProposal`, the application would be passed 144 this metadata along with the transaction, allowing the application to use it to perform 145 any necessary filtering. 146 147 If either of these proposed metadata handling techniques are selected, it's likely 148 useful to enable applications to gossip metadata along with the transaction it is 149 gossiping. This could easily take the form of an opaque proto message that is 150 gossiped along with the transaction. 151 152 ## References 153 154 [eth-whitepaper-messages]: https://ethereum.org/en/whitepaper/#messages-and-transactions 155 [gas-add-pr]: https://github.com/tendermint/tendermint/pull/2360 156 [cosmos-sdk-gas]: https://github.com/cosmos/cosmos-sdk/blob/c00cedb1427240a730d6eb2be6f7cb01f43869d3/docs/basics/gas-fees.md 157 [cosmos-sdk-fees]: https://github.com/cosmos/cosmos-sdk/blob/c00cedb1427240a730d6eb2be6f7cb01f43869d3/docs/basics/tx-lifecycle.md#gas-and-fees 158 [anoma-gas]: https://github.com/anoma/anoma/blob/6974fe1532a59db3574fc02e7f7e65d1216c1eb2/docs/src/specs/ledger.md#transaction-execution 159 [cosmos-sdk-fee]: https://github.com/cosmos/cosmos-sdk/blob/c00cedb1427240a730d6eb2be6f7cb01f43869d3/types/tx/tx.pb.go#L780-L794 160 [issue-7750]: https://github.com/tendermint/tendermint/issues/7750 161 [reap-max-bytes-max-gas]: https://github.com/tendermint/tendermint/blob/1ac58469f32a98f1c0e2905ca1773d9eac7b7103/internal/mempool/types.go#L45 162 [add-mempool-error]: https://github.com/tendermint/tendermint/blob/205bfca66f6da1b2dded381efb9ad3792f9404cf/rpc/coretypes/responses.go#L239