Skip to content

Commit

Permalink
sketch the spec of feemarket module
Browse files Browse the repository at this point in the history
WIP cosmos#9963

Merge the idea of [feemarket module in ethermint](https://github.com/tharsis/ethermint/tree/main/x/feemarket)
into cosmos-sdk.
  • Loading branch information
yihuang committed Oct 29, 2021
1 parent e01fa1a commit 5d0b791
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 0 deletions.
10 changes: 10 additions & 0 deletions x/feemarket/spec/01_concepts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!--
order: 1
-->

# Concepts

Adopt EIP 1559 idea into cosmos-sdk.

- Maintain a minimal gas prices in consensus, which is ajusted based on total gas used in the previous block. It's called base gas price, to distinguish with the `minimal-gas-prices` configured in each node.
- In checkTx context, the `minimal-gas-prices` are also repected if it's bigger than the consensus one.
45 changes: 45 additions & 0 deletions x/feemarket/spec/02_state_transitions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<!--
order: 2
-->

# State Transitions

This document describes the state transition operations pertaining to the base gas prices.

## Block Gas Used

The total gas used by current block is stored in chain state at the `EndBlock` event.

It's initialized to `-1` in `InitGenesis`.

## Base Gas Prices

### Init

The base gas prices are initialized to the parameter `InitialBasePrices` in `InitGenesis` event.

### Adjust

Base gas prices are adjusted in the `EndBlock` event according to the total gas used in the previous block.

```golang
parentGP := GetState(BaseGasPrices)
parentGasUsed := GetState(BlockGasUsed)

var expectedGP sdk.Coins
if parentGasUsed == -1:
expectedGP = parentGP
else if parentGasUsed == params.BlockGasTarget:
expectedGP = parentGP
else if parentGasUsed > params.BlockGasTarget:
delta = parentGasUsed - params.BlockGasTarget
delta = max(parentBaseFee * delta / params.BlockGasTarget / params.BaseGasPriceChangeDenominator, 1)
expectedGP = parentBaseFee + delta
else:
delta = params.BlockGasTarget - parentGasUsed
delta = parentGP * delta / params.BlockGasTarget / params.BaseGasPriceChangeDenominator
expectedGP = parentGP - delta

SetState(BaseGasPrices, expectedGP)
```

42 changes: 42 additions & 0 deletions x/feemarket/spec/03_antehandlers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!--
order: 3
-->

# AnteHandlers

## Decorators

### `MempoolFeeDecorator`

The `MempoolFeeDecorator` in `x/auth` module should check the `BaseGasPrices` along with the `minimal-gas-prices`.

```golang
gas := tx.GetGas()
baseGP := GetState(BaseGasPrices)
minGP := ctx.MinGasPrices() // it's zero in deliverTx context

requiredFees := make(sdk.Coins, 0)
if baseGP.IsZero() {
// base gas prices are not enabled, check the minimal-gas-prices only
for i, gp := range minGasPrices {
fee := gp.Amount.Mul(gas).Ceil().RoundInt()
requiredFees = append(requiredFees, sdk.NewCoin(gp.Denom, fee))
}
} else {
// check `tx.GetFee() > max(baseGP, minGP) * tx.GetGas()`
for i, gp := range baseGP {
fee := gp.Amount.Mul(gas).Ceil().RoundInt()
amt := minGasPrices.AmountOf(gp.Denom)
if amt > fee {
fee = amt
}
requiredFees = append(requiredFees, sdk.NewCoin(gp.Denom, fee))
}
}

feeCoins := tx.GetFee()
if !feeCoins.IsAnyGTE(requiredFees) {
return fmt.Errorf("insufficient fees; got: %s required: %s", feeCoins, requiredFees)
}
```

9 changes: 9 additions & 0 deletions x/feemarket/spec/04_end_block.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!--
order: 4 -->

# End-Block

Each abci end block call, `x/feemarket` module adjust `BaseGasPrices` and record the `BlockGasUsed`.

- [Adjust `BaseGasPrices`](02_state_transitions.md#base-gas-prices)
- [Record `BlockGasUsed`](#02_state_transitions.md#block-gas-used)
14 changes: 14 additions & 0 deletions x/feemarket/spec/05_events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!--
order: 5 -->

# Events

The `x/feemarket` module emits the following events:

## EndBlocker

| Type | Attribute Key | Attribute Value |
| ---------- | --------------- | --------------- |
| block_gas | height | {blockHeight} |
| block_gas | amount | {blockGasUsed} |
| fee_market | base_gas_prices | {baseGasPrices} |
14 changes: 14 additions & 0 deletions x/feemarket/spec/06_params.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!--
order: 6 -->

# Parameters

The `x/feemarket` module contains the following parameters:

| Key | Type | Example |
| ----------------------------- | ------ | ----------- |
| BlockGasTarget | uint32 | "2000000" |
| InitialBaseGasPrices | Coins | "1000uatom" |
| BaseGasPriceChangeDenominator | uint32 | 8 |

- `BlockGasTarget`, should be smaller than `ConsensusParams.Block.MaxGas` if the latter one is specified.
23 changes: 23 additions & 0 deletions x/feemarket/spec/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!--
order: 0
title: Feemarket Overview
parent:
title: "feemarket"
-->

# `feemarket`

## Abstract

This document specifies the feemarket module of the Cosmos SDK.

The feemarket module implements a base gas prices in consensus level.

## Contents

1. **[Concepts](01_concepts.md)**
2. **[State Transitions](02_state_transitions.md)**
3. **[Ante Handlers](03_antehandlers.md)**
4. **[End Block](04_end_block.md)**
5. **[Events](05_events.md)**
6. **[Params](06_params.md)**

0 comments on commit 5d0b791

Please sign in to comment.