Skip to content

Commit

Permalink
docs(gas/fees): Update block gas documentation (#20128)
Browse files Browse the repository at this point in the history
  • Loading branch information
samricotta authored Apr 22, 2024
1 parent 0aff4f2 commit 96c243e
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions docs/learn/beginner/04-gas-fees.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,25 @@ Gas consumption can be done manually, generally by the module developer in the [

### Block Gas Meter

`ctx.BlockGasMeter()` is the gas meter used to track gas consumption per block and make sure it does not go above a certain limit. A new instance of the `BlockGasMeter` is created each time [`FinalizeBlock`](../advanced/00-baseapp.md#finalizeblock) is called. The `BlockGasMeter` is finite, and the limit of gas per block is defined in the application's consensus parameters. By default, Cosmos SDK applications use the default consensus parameters provided by CometBFT:
`ctx.BlockGasMeter()` is the gas meter used to track gas consumption per block and make sure it does not go above a certain limit.

```go reference
https://github.com/cometbft/cometbft/blob/v0.37.0/types/params.go#L66-L105
During the genesis phase, gas consumption is unlimited to accommodate initialisation transactions.

```go
app.finalizeBlockState.SetContext(app.finalizeBlockState.Context().WithBlockGasMeter(storetypes.NewInfiniteGasMeter()))
```

When a new [transaction](../advanced/01-transactions.md) is being processed via `FinalizeBlock`, the current value of `BlockGasMeter` is checked to see if it is above the limit. If it is, the transaction fails and returned to the consensus engine as a failed transaction. This can happen even with the first transaction in a block, as `FinalizeBlock` itself can consume gas. If not, the transaction is processed normally. At the end of `FinalizeBlock`, the gas tracked by `ctx.BlockGasMeter()` is increased by the amount consumed to process the transaction:
Following the genesis block, the block gas meter is set to a finite value by the SDK. This transition is facilitated by the consensus engine (e.g., CometBFT) calling the `RequestFinalizeBlock` function, which in turn triggers the SDK's `FinalizeBlock` method. Within `FinalizeBlock`, `internalFinalizeBlock` is executed, performing necessary state updates and function executions. The block gas meter, initialised each with a finite limit, is then incorporated into the context for transaction execution, ensuring gas consumption does not exceed the block's gas limit and is reset at the end of each block.

Modules within the Cosmos SDK can consume block gas at any point during their execution by utilising the `ctx`. This gas consumption primarily occurs during state read/write operations and transaction processing. The block gas meter, accessible via `ctx.BlockGasMeter()`, monitors the total gas usage within a block, enforcing the gas limit to prevent excessive computation. This ensures that gas limits are adhered to on a per-block basis, starting from the first block post-genesis.

```go
ctx.BlockGasMeter().ConsumeGas(
ctx.GasMeter().GasConsumedToLimit(),
"block gas meter",
)
gasMeter := app.getBlockGasMeter(app.finalizeBlockState.Context())
app.finalizeBlockState.SetContext(app.finalizeBlockState.Context().WithBlockGasMeter(gasMeter))
```

This above shows the general mechanism for setting the block gas meter with a finite limit based on the block's consensus parameters.

## AnteHandler

The `AnteHandler` is run for every transaction during `CheckTx` and `FinalizeBlock`, before a Protobuf `Msg` service method for each `sdk.Msg` in the transaction.
Expand Down

0 comments on commit 96c243e

Please sign in to comment.