Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: sketch the spec of feemarket module #10463

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 price in consensus, which is adjusted 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 respected 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`.
Comment on lines +11 to +13
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to add another .md file for how the state (kv store) looks like? In particular:

  • under which key is this total gas stored in the substore? (e.g. 0x0)
  • which encoding to use for the integer?

Also see SPEC_SPEC for more info.


## 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)
yihuang marked this conversation as resolved.
Show resolved Hide resolved
parentGasUsed := GetState(BlockGasUsed)

var expectedGP sdk.Coins
if parentGasUsed == -1:
expectedGP = parentGP
else if parentGasUsed == params.BlockGasTarget:
expectedGP = parentGP
yihuang marked this conversation as resolved.
Show resolved Hide resolved
else if parentGasUsed > params.BlockGasTarget:
delta = parentGasUsed - params.BlockGasTarget
delta = max(parentGP * delta / params.BlockGasTarget / params.BaseGasPriceChangeDenominator, 1)
expectedGP = parentGP + delta
yihuang marked this conversation as resolved.
Show resolved Hide resolved
else:
delta = params.BlockGasTarget - parentGasUsed
delta = parentGP * delta / params.BlockGasTarget / params.BaseGasPriceChangeDenominator
expectedGP = parentGP - delta
yihuang marked this conversation as resolved.
Show resolved Hide resolved

SetState(BaseGasPrices, expectedGP)
```

yihuang marked this conversation as resolved.
Show resolved Hide resolved
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()
yihuang marked this conversation as resolved.
Show resolved Hide resolved
requiredFees = append(requiredFees, sdk.NewCoin(gp.Denom, fee))
}
} else {
// check `tx.GetFee() > max(baseGP, minGP) * tx.GetGas()`
yihuang marked this conversation as resolved.
Show resolved Hide resolved
for i, gp := range baseGP {
fee := gp.Amount.Mul(gas).Ceil().RoundInt()
amt := minGasPrices.AmountOf(gp.Denom)
if amt > fee {
fee = amt
}
yihuang marked this conversation as resolved.
Show resolved Hide resolved
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)
yihuang marked this conversation as resolved.
Show resolved Hide resolved
}
```

yihuang marked this conversation as resolved.
Show resolved Hide resolved
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 or equal to `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.
Copy link
Contributor

@liamsi liamsi Oct 30, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The feemarket module implements a base gas prices in consensus level.
The feemarket module implements a base gas price at the consensus level.

or: base gas prices


## 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)**