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

docs: update globalfee.md according to the bypass-msg-types migration #2463

Merged
merged 17 commits into from
Jun 19, 2023
195 changes: 137 additions & 58 deletions docs/modules/globalfee.md
Original file line number Diff line number Diff line change
@@ -1,69 +1,75 @@
# Gaia Fees and Fees Checks
# Gaia Fee and Fees Checks

## Fee Parameters
The CosmosHub allows managing fees using 3 parameters:
The CosmosHub allows managing fees using 4 parameters. At the network level, there are three parameters from globalfee modules (`MinimumGasPricesParam`, `BypassMinFeeMsgTypes`, and `MaxTotalBypassMinFeeMsgGasUsage`) that can be set by gov proposal. Additionally, a fourth parameter which enables individual nodes to impose supplementary fee amount.

1. setting global fees (`MinimumGasPricesParam`)
Global fees are defined at the network level by setting `MinimumGasPricesParam`, via [Gov Proposals](https://hub.cosmos.network/main/governance/proposals/)
1. global fees (`MinimumGasPricesParam`).\
global fees `MinimumGasPricesParam` is established at the network level through globalfee params set via Governance Proposal, it sets a fee requirements that the entire network must adhere to.

2. `minimum-gas-prices`
This parameter is part of the node configuration, it can be set in the `config/app.toml` configuration file.
*Please note: in this context, "globalfee" or "Globalfee" are used to refer to the globalfee module, while "global fees" is referring to the `MinimumGasPricesParam` in the globalfee module's params.*

3. `bypass-min-fee-msg-types`
This parameter is part of the node configuration, it can be set in the `config/app.toml` configuration file.
This represents a list of message types that will be excluded from paying any fees for inclusion in a block.

Both global fees (`MinimumGasPricesParam`) and `minimum-gas-prices` represent a list of coins, each denoted by an amount and domination as defined by [sdk.DecCoins](https://github.com/cosmos/cosmos-sdk/blob/82ce891aa67f635f3b324b7a52386d5405c5abd0/types/dec_coin.go#L158)
2. `minimum-gas-prices` in `app.toml`\
By adjusting the `minimum-gas-prices` parameter in `app.toml`, nodes can enforce a fee that is higher than the globally defined `MinimumGasPricesParam`. However, it's importantht to note that this configuration solely determines whether transactions are eligible to enter this specific node's mempool.

*Please note: in this context, `minimum-gas-prices` are used to refer to the local fee requirement that nodes can set in their `app.toml`, while `MinimumGasPricesParam` is a parameter in the globalfee module, which is the fee requirement at network level.*

## Concepts

## Global Fees

Global fees consist of a list of `sdk.DecCoins` e.g., `[1uatom, 2stake]`.
Every transaction must pay per unit of gas **at least** one of the amounts stated in this list in the corresponding denomination (denom). By this notion, global fees allow a network to impose a minimum transaction fee.
3. `BypassMinFeeMsgTypes` and `MaxTotalBypassMinFeeMsgGasUsage`.\
These two parameters are also part of the globalfee params from gaiad v11.0.0. They can be changed through Gov Proposals. `BypassMinFeeMsgTypes` represents a list of message types that will be excluded from paying any fees for inclusion in a block, `MaxTotalBypassMinFeeMsgGasUsage` is the limit placed on gas usage for `BypassMinFeeMsgTypes`.

The paid fees must be paid in at least one denom from the global fees list and the corresponding amount per unit of gas must be greater than or equal to the corresponding amount in the global fees list.
## Concepts
yaruwangway marked this conversation as resolved.
Show resolved Hide resolved

A global fees list must meet the following properties:
- fees have to be alphabetically sorted by denom;
- fees must have non-negative amount, with a valid and unique denom (i.e. no duplicate denoms are allowed).
## Global Fee module

The globalfee module has three parameters that can be set by governance proposal type `param-change`:
- `MinimumGasPricesParam`
- `BypassMinFeeMsgTypes`
- `MaxTotalBypassMinFeeMsgGasUsage`

There are **two exceptions** from the global fees rules that allow zero fee transactions:
### Globalfee Params: `MinimumGasPricesParam`

1. Transactions that contain only [message types that can bypass the minimum fee](#bypass-fees-message-types) may have zero fees. We refer to this as _bypass transactions_. Node operators can choose to define these message types (for each node) via the `bypass-fee-message-types` configuration parameter.
Network level, global fees consist of a list of [`sdk.DecCoins`](https://github.com/cosmos/cosmos-sdk/blob/82ce891aa67f635f3b324b7a52386d5405c5abd0/types/dec_coin.go#L158).
Every transaction must pay per unit of gas, **at least**, in one of the denominations (denoms) amounts in the list. This allows the globalfee module to impose a minimum transaction fee for all transactions for a network.

2. One of the entries in the global fees list has a zero amount, e.g., `0uatom`, and the corresponding denom, e.g., `uatom`, is not present in `minimum-gas-prices`.
Requirements for the fees include:
- fees have to be alphabetically sorted by denom
- fees must have non-negative amount, with a valid and unique denom (i.e. no duplicate denoms are allowed)

Additionally, node operators may set additional minimum gas prices which can be larger than the _global_ minimum gas prices defined on chain.
There are **two exceptions** from the global fees rules that allow zero fee transactions:

1. Transactions that contain only message types that can bypass the minimum fee requirement and for which the total gas usage of these bypass messages does not exceed `maxTotalBypassMinFeeMsgGasUsage` may have zero fees. We refer to this as _bypass transactions_.

### minimum-gas-prices
2. One of the entries in the global fees list has a zero amount, e.g., `0uatom`, and the corresponding denom, e.g., `uatom`, is not present in `minimum-gas-prices` in `app.toml`, or node operators may set additional `minimum-gas-prices` in `app.toml` also zero coins.

The `minimum-gas-prices` config parameter allows node operators to impose additional requirements for minimum fees. The following rules apply:
### Globalfee Params: `BypassMinFeeMsgTypes` and `MaxTotalBypassMinFeeMsgGasUsage`

- The denoms in `min-gas-prices` that are not present in the global fees list are ignored.
- The amounts in `min-gas-prices` are considered only if they are greater than the amounts for the corresponding denoms in the global fees list.
Bypass minimum fee messages are messages that are exempt from paying fees. The above global fees and the below local `minimum-gas-prices` checks do not apply for transactions that satisfy the following conditions:

## Bypass Fees Message Types
- Transaction contains only bypass message types defined in `BypassMinFeeMsgTypes`.
- The total gas used is less than or equal to `MaxTotalBypassMinFeeMsgGasUsage`.
- In case of non-zero transaction fees, the denom has to be a subset of denoms defined in the global fees list.

Bypass messages are messages that are exempt from paying fees. The above global fees and `minimum-gas-prices` checks do not apply for transactions that satisfy the following conditions:
Starting from gaiad `v11.0.0`, `BypassMinFeeMsgTypes` and `MaxTotalBypassMinFeeMsgGasUsage` are part of global fee params and can be proposed at network level. The default values are: `bypass-min-fee-msg-types=[
"/ibc.core.channel.v1.MsgRecvPacket",
"/ibc.core.channel.v1.MsgAcknowledgement",
"/ibc.core.client.v1.MsgUpdateClient",
"/ibc.core.channel.v1.MsgTimeout",
"/ibc.core.channel.v1.MsgTimeoutOnClose"
]` and default `maxTotalBypassMinFeeMsgGasUsage=1,000,000`

- Contains only bypass message types, i.e., bypass transactions.
- The total gas used is less than or equal to `MaxTotalBypassMinFeeMsgGasUsage`. Note: the current `MaxTotalBypassMinFeeMsgGasUsage` is set to `1,000,000`.
- In case of non-zero transaction fees, the denom has to be a subset of denoms defined in the global fees list.
From gaiad v11.0.0, nodes that have the `bypass-min-fee-msg-types` field in their `app.toml` configuration are **not utilized**. Therefore, node operators have the option to either leave the field in their configurations or remove it. Node inited by gaiad v11.0.0 or later does not have `bypass-min-fee-msg-types` field in the `app.toml`.
yaruwangway marked this conversation as resolved.
Show resolved Hide resolved

Node operators can configure `bypass-min-fee-msg-types` in `config/app.toml`.
Before gaiad `v11.0.0`, `bypass-min-fee-msg-types` can be set by each node in `app.toml`, and [the bypass messages gas usage on average should not exceed `maxBypassMinFeeMsgGasUsage`=200,000](https://github.com/cosmos/gaia/blob/682770f2410ab0d33ac7f0c7203519d7a99fa2b6/x/globalfee/ante/fee.go#L69).

- Nodes created using Gaiad `v7.0.2` - `v10.0.x` use `["/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.channel.v1.MsgAcknowledgement","/ibc.applications.transfer.v1.MsgTransfer"]` as defaults.
- Nodes created using Gaiad `v11.0.x` or later use `["/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.channel.v1.MsgAcknowledgement","/ibc.applications.transfer.v1.MsgTransfer", "/ibc.core.channel.v1.MsgTimeout", "/ibc.core.channel.v1.MsgTimeoutOnClose"]` as defaults.
- Node Nodes with `bypass-min-fee-msg-types = []` or missing this field in `app.toml` also use default bypass message types.
- Nodes created using Gaiad `v7.0.1` and `v7.0.0` do not have `bypass-min-fee-msg-types` configured in `config/app.toml` - they are also using same default values as in `v7.0.2`. The `bypass-min-fee-msg-types` config option can be added to `config/app.toml` before the `[telemetry]` field.
- Nodes created using gaiad `v7.0.1` and `v7.0.0` do not have `bypass-min-fee-msg-types` configured in `config/app.toml` - they are also using same default values as in `v7.0.2`. The `bypass-min-fee-msg-types` config option can be added to `config/app.toml` before the `[telemetry]` field.

An example of `bypass-min-fee-msg-types` in `app.toml`:
An example of `bypass-min-fee-msg-types` in `app.toml` **before** gaiad v11.0.0:

```shell
```

###############################################################################
### Custom Gaia Configuration ###
Expand All @@ -77,6 +83,15 @@ bypass-min-fee-msg-types = ["/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.cha
```


### minimum-gas-prices (local fee requirement)

The `minimum-gas-prices` parameter enables node operators to set its minimum fee requirements, and it can be set in the `config/app.toml` file. Please note: if `minimum-gas-prices` is set to include zero coins, the zero coins are sanitized when [`SetMinGasPrices`](https://github.com/cosmos/gaia/blob/76dea00bd6d11bfef043f6062f41e858225820ab/cmd/gaiad/cmd/root.go#L221).
When setting `minimum-gas-prices`, it's important to keep the following rules in mind:

- The denoms in `min-gas-prices` that are not present in the global fees list are ignored.
- The amounts in `min-gas-prices` that are lower than global fees `MinimumGasPricesParam` are ignored.
- The amounts in `min-gas-prices` are considered as fee requirement only if they are greater than the amounts for the corresponding denoms in the global fees list.

## Fee AnteHandler Behaviour

The denoms in the global fees list and the `minimum-gas-prices` param are merged and de-duplicated while keeping the higher amounts. Denoms that are only in the `minimum-gas-prices` param are discarded.
Expand All @@ -85,30 +100,45 @@ If the denoms of the transaction fees are a subset of the merged fees and at lea

## Queries

CLI queries can be used to retrieve the global fee value:
CLI queries can be used to retrieve the globalfee params:

```shell
gaiad q globalfee minimum-gas-prices
# or
gaiad q params subspace globalfee MinimumGasPricesParam
gaiad q globalfee params

{
"minimum_gas_prices": [
{
"denom": "uatom",
"amount": "0.002000000000000000"
},
],
"bypass_min_fee_msg_types": [
"/ibc.core.channel.v1.MsgRecvPacket",
"/ibc.core.channel.v1.MsgAcknowledgement",
"/ibc.core.client.v1.MsgUpdateClient",
"/ibc.core.channel.v1.MsgTimeout",
"/ibc.core.channel.v1.MsgTimeoutOnClose"
],
"max_total_bypass_min_fee_msg_gas_usage": "2000000"
}
```

If the global fee is not set, the query returns an empty global fees list: `minimum_gas_prices: []`. In this case the Cosmos Hub will use `0uatom` as global fee in this case (the default fee denom).
If the global fees `MinimumGasPricesParam` is not set, the query returns an empty global fees list: `minimum_gas_prices: []`. In this case the Cosmos Hub will use `0uatom` as global fee in this case (the default fee denom).

## Setting Up Global Fees via Gov Proposals
## Setting Up Globalfee Params via Gov Proposals

An example of setting up a global fee by a gov proposals is shown below.

```shell
gov submit-proposal param-change proposal.json
````

A `proposal.json` example:
A `proposal.json` example to change the `MinimumGasPricesParam` in globalfee params:

```json
```
{
"title": "Global fees Param Change",
"description": "Update global fees",
"title": "Global fee Param Change",
"description": "Update global fee",
"changes": [
{
"subspace": "globalfee",
Expand All @@ -119,17 +149,48 @@ A `proposal.json` example:
"deposit": "1000stake"
}
```

**Note:** in the above "value" field, coins must sorted alphabetically by denom.

A `proposal.json` example to change the `bypassMinFeeMsgTypes` in globalfee params:

```
{
"title": "Globalfee Param Change",
"description": "Update globalfee Params",
"changes": [
{
"subspace": "Globalfee",
"key": "BypassMinFeeMsgTypes",
"value": ["/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward", "/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.client.v1.MsgUpdateClient"]
}
],
"deposit": "1000000uatom"
}
```
A `proposal.json` example to change the `maxTotalBypassMinFeeMsgGasUsage` in globalfee params:
```
{
"title": "Globalfee Param Change",
"description": "Update globalfee Params",
"changes": [
{
"subspace": "globalfee",
"key": "MaxTotalBypassMinFeeMsgGasUsage",
"value": 5000
}
],
"deposit": "1000000uatom"
}
```


## Examples

Here are a few examples to clarify the relationship between global fees, minimum-gas-prices and transaction fees.

**Note:** Transactions can include zero-coin fees. However, these fees are removed from the transaction fees during the fee [parsing](https://github.com/cosmos/cosmos-sdk/blob/e716e4103e934344aa7be6dc9b5c453bdec5f225/client/tx/factory.go#L144) / [santitizing](https://github.com/cosmos/cosmos-sdk/blob/e716e4103e934344aa7be6dc9b5c453bdec5f225/types/dec_coin.go#L172) before reaching the fee AnteHandler.
**Note:** Transactions can include zero-coin fees. However, these fees are removed from the transaction fees during the fee [parsing](https://github.com/cosmos/cosmos-sdk/blob/e716e4103e934344aa7be6dc9b5c453bdec5f225/client/tx/factory.go#L144) / [sanitizing](https://github.com/cosmos/cosmos-sdk/blob/e716e4103e934344aa7be6dc9b5c453bdec5f225/types/dec_coin.go#L172) before reaching the fee AnteHandler.
This means `paidfee = "1uatom, 0stake"` and `paidfee = "1uatom"` are equivalent, and similarly, `paidfee = "0uatom"` is equivalent to `paidfee = ""`.
In the following examples, zero-coin fees are removed from the transaction fees.
In the following examples, zero-coin fees are removed from the transaction fees, globalfee refers to `MinimumGasPricesParam` in globalfee params, minimum-gas-prices refers to the local `minimum-gas-prices` setup in `app.toml`.

### Case 1

Expand Down Expand Up @@ -201,22 +262,40 @@ Note that the required amount of `uatom` in globalfee is overwritten by the amou

### Case 7

**Setting:** globalfee=[0.1uatom], minimum-gas-prices=[0.2uatom, 1stake], gas=200000, bypass-min-fee-msg-types = ["/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"]
**Setting:** globalfee=[0.1uatom], minimum-gas-prices=[0.2uatom, 1stake], gas=600,000,\
max-total-bypass-min-fee-msg-gas-usage=1,000,000,\
bypass-min-fee-msg-types = [\
"/ibc.core.channel.v1.MsgRecvPacket",\
"/ibc.core.channel.v1.MsgAcknowledgement",\
"/ibc.core.client.v1.MsgUpdateClient",\
"/ibc.core.channel.v1.MsgTimeout",\
"/ibc.core.channel.v1.MsgTimeoutOnClose"\
]

Note that the required amount of `uatom` in globalfee is overwritten by the amount in minimum-gas-prices.
Also, the `1stake` in minimum-gas-prices is ignored.

- msg withdraw-all-rewards with paidfee="", `pass`
- msg withdraw-all-rewards with paidfee="200000 * 0.05uatom", `pass`
- msg withdraw-all-rewards with paidfee="200000 * 1stake", `fail` (unexpected denom)
- msgs=["/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.client.v1.MsgUpdateClient"] with paidfee="", `pass`
- msgs=["/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.client.v1.MsgUpdateClient"] with with paidfee="600000 * 0.05uatom", `pass`
- msgs= ["/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"] with paidfee="", `fail`
- msgs=["/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.client.v1.MsgUpdateClient", "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward] with paidfee="", `fail` (transaction contains non-bypass messages)
- msgs=["/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.client.v1.MsgUpdateClient", "/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward] with paidfee="600000 * 0.2uatom", `pass`
- msgs=["/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.client.v1.MsgUpdateClient"] with paidfee="600000 * 1stake", `fail` (unexpected denom)

### Case 8

**Setting:** globalfee=[1uatom], minimum-gas-prices="", gas=300000, bypass-min-fee-msg-types = ["/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward"]

- msg withdraw-all-rewards with paidfee="", `fail` (gas limit exceeded for bypass transactions)
- msg withdraw-all-rewards with paidfee="300000 * 0.5uatom", `fail` (gas limit exceeded for bypass transactions, insufficient funds)
- msg withdraw-all-rewards with paidfee="300000 * 1uatom", `pass`
**Setting:** globalfee=[1uatom], minimum-gas-prices="0uatom", gas=1,100,000 or 200,\
max-total-bypass-min-fee-msg-gas-usage=1,000,000,\
bypass-min-fee-msg-types = [\
"/ibc.core.channel.v1.MsgRecvPacket",\
"/ibc.core.channel.v1.MsgAcknowledgement",\
"/ibc.core.client.v1.MsgUpdateClient",\
"/ibc.core.channel.v1.MsgTimeout",\
"/ibc.core.channel.v1.MsgTimeoutOnClose"\
]
- msgs=["/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.client.v1.MsgUpdateClient"] with paidfee="" and gas=1,100,000, `fail` (gas limit exceeded for bypass transactions)
- msgs=["/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.client.v1.MsgUpdateClient"] with paidfee="200 * 1uatom" and gas=200, `fail` (insufficient funds)
- msgs=["/ibc.core.channel.v1.MsgRecvPacket", "/ibc.core.client.v1.MsgUpdateClient"] with paidfee="1,100,000 * 1uatom", `pass`

## References

Expand Down