Skip to main content

feepolicy

Abstract

This document specifies the feepolicy module, which allows defining opt-in fee deduction policy for the network transactions.

This module has been designed to define opt-in fee discounts for specific accounts on specific module transactions.

For the transactions repeated in multiple modules, the CheckDiscount method should be overwritten in the discounted module keeper to avoid unwanted fee discounts.

Contents

  1. Concepts
  2. State
  3. Keeper
  4. Events
  5. Client
  6. AnteHandlers

Concepts

Fee Discounts

Fee discounts employ a wrapper over the COsmos-sdk fee deduction with certain custom discounts. Feepolicy module employs two kinds of discounts

  • percent: percentage amount for the discount applied
  • fixed: only the fixed set amount will be deducted

Registering Fee Discounts

The feepolicy module allows to apply fee discounts for specific accounts and transactions as defined in this structure:

{
"discounts": [
{
"address": "guru1...",
"modules": [
{
"module": "[module name]",
"discounts": [
{
"discountType": "[percent/fixed]",
"msgType": "[/app.module.version.Msg...]",
"amount": "[math.LegacyDec]"
}
]
}
]
}
...
]
}

Tips

  • when using discountType: "percent", the amount defines the amount of discount, not the deducted amount
  • amount value cannot be 0 or negative
  • for registering 0 fees for the account, use discountType: "percent" and amount: "100" combination

State

The x/feepolicy module keeps in the state variables for fee policy enforcement:

DescriptionKeyValueStore
ModeratorAddressmodule moderator address[]byte{1}[]byte{string}KV
DiscountsApplied account discounts[]byte{2}[]AccountdiscountKV

Genesis

Moderator Address

If the moderator_address is not defined at the genesis state, the gov module address is defined as the default moderator.

Keeper

The x/feepolicy module provides this exported keeper that can be passed to other modules, which require access to the fee discounts

type Keeper interface {
GetModeratorAddress(ctx sdk.Context) string
GetPaginatedDiscounts(ctx sdk.Context, pagination *query.PageRequest) ([]types.AccountDiscount, *query.PageResponse, error)
GetAccountDiscounts(ctx sdk.Context, accStr string) (types.AccountDiscount, bool)
GetModuleDiscounts(ctx sdk.Context, accStr, module string) ([]types.Discount, bool)
GetDiscount(ctx sdk.Context, feePayerAddr string, msgs []sdk.Msg) types.Discount
}

The x/feepolicy module keeper also passes other module keepers into its own keeper as the object of ModuleKeepers[module]Keeper. Example usage: ModuleKeepers["bank"] = BankKeeper

Each ModuleKeeper is expected to implement the interface methods:

type ModuleKeeper interface {
CheckDiscount(ctx sdk.Context, discounts Discount, msgs []sdk.Msg) bool
}

ModuleKeeper Injection

ModuleKeeper injection is required only if the fee discounts apply to the injected module common transactions.

Example 1

For the bank module transactions, no injection required as this module implements and interfaces only its own custom msgs

Example 2

For ibc-related modules, such as x/ibc-transfer, there are several common msgs passed through, so, the module keeper needs to implement the custom checking gateway method and its keeper needs to be injected to avoid unwanted discount applications.

Events

The x/feepolicy module emits the following events:

MsgRegisterDiscounts

TypeAttribute KeyAttribute Value
register_discountsmoderator{moderatorAddress}
register_discountsaddress{discountAddress}
register_discountsdiscount_type{discountType}
register_discountsmsg_type{discountMsgType}
register_discountsamount{discountAmount}

MsgRemoveDiscounts

TypeAttribute KeyAttribute Value
remove_discountsmoderator{moderatorAddress}
remove_discountsaddress{discountAddress}
remove_discountsdiscount_type{discountType}
remove_discountsmsg_type{discountMsgType}
remove_discountsamount{discountAmount}

MsgChangeModerator

TypeAttribute KeyAttribute Value
change_moderator_addressmoderator{moderatorAddress}
change_moderator_addressaddress{newModeratorAddress}

Client

CLI

A user can query and interact with the feepolicy module using the CLI.

Queries

The query commands allow users to query feepolicy state.

CommandSubcommandDescription
query feepolicydiscountsGet all discounts
query feepolicydiscount [address]Get discounts for address
query feepolicymoderator_addressGet current moderator address
gurud query feepolicy --help
Discounts

The discounts command allows users to query the all registered discounts.

gurud query feepolicy discounts [flags]

Example:

gurud query feepolicy discounts ...

Example Output:

discounts:
- address: guru1cml96vmptgw99syqrrz8az79xer2pcgpawsch9
modules:
- discounts:
- amount: "100.000000000000000000"
discountType: percent
msgType: /cosmos.bank.v1beta1.MsgSend
module: bank
- address: guru1gzsvk8rruqn2sx64acfsskrwy8hvrmaf6dvhj3
modules:
- discounts:
- amount: "50.000000000000000000"
discountType: percent
msgType: /cosmos.bank.v1beta1.MsgSend
module: bank
- address: guru1jcltmuhplrdcwp7stlr4hlhlhgd4htqhtx0smk
modules:
- discounts:
- amount: "1000.000000000000000000"
discountType: fixed
msgType: /cosmos.bank.v1beta1.MsgSend
module: bank
pagination:
next_key: null
total: "3"
Discounts

The discount command allows users to query the registered disacounts for specific account.

gurud query feepolicy discount [address] [flags]

Example:

gurud query feepolicy discount guru1cml96vmptgw99syqrrz8az79xer2pcgpawsch9 ...

Example Output:

discount:
address: guru1cml96vmptgw99syqrrz8az79xer2pcgpawsch9
modules:
- discounts:
- amount: "100.000000000000000000"
discountType: percent
msgType: /cosmos.bank.v1beta1.MsgSend
module: bank
ModeratorAddress

The moderator_address command allows users to query the current moderator address.

gurud query feepolicy moderator_address [flags]

Example:

gurud query feepolicy moderator_address ...

Example Output:

moderator_address: guru1gzsvk8rruqn2sx64acfsskrwy8hvrmaf6dvhj3

Transactions

The tx commands allow the moderator to change the feepolicy state.

CommandSubcommandDescription
tx feepolicyregister_discountsRegister new discounts in bulk
tx feepolicyremove_discountsRemove registered discounts
tx feepolicychange_moderatorChange the moderator address
RegisterDiscounts

The register_discounts command allows the moderator to register new fee discounts in batch. THis overwrites the existing discounts for the same address, module and msgType

gurud tx feepolicy register_discounts PATH_TO_JSON_FILE [flags]

Example:

gurud tx feepolicy register_discounts ./discounts.json --from moderator_address ...

discounts.json example

{
"discounts": [
{
"address": "guru1gzsvk8rruqn2sx64acfsskrwy8hvrmaf6dvhj3",
"modules": [
{
"module": "bank",
"discounts": [
{
"discountType": "percent",
"msgType": "/cosmos.bank.v1beta1.MsgSend",
"amount": "50"
}
]
},
{
"module": "staking",
"discounts": [
{
"discountType": "fixed",
"msgType": "/cosmos.staking.v1beta1.MsgDelegate",
"amount": "1000",
}
]
}
]
},
{
"address": "guru1jcltmuhplrdcwp7stlr4hlhlhgd4htqhtx0smk",
"modules": [
{
"module": "gov",
"discounts": [
{
"discountType": "percent",
"msgType": "/cosmos.gov.v1beta1.MsgSubmitProposal",
"amount": "100",
}
]
}
]
}
]
}
RemoveDiscounts

The remove_discounts command allows the moderator to remove existing discount for the address.

gurud tx feepolicy remove_discounts ADDRESS MODULE MSG_TYPE [flags]

Example:

gurud tx feepolicy remove_discounts guru1gzsvk8rruqn2sx64acfsskrwy8hvrmaf6dvhj3 bank /cosmos.bank.v1beta1.MsgSend --from moderator_address ...
ChangeModerator

The change_moderator command allows the moderator to change the current moderator address.

gurud tx feepolicy change_moderator NEW_MODERATOR_ADDRESS [flags]

Example:

gurud tx feepolicy change_moderator guru1gzsvk8rruqn2sx64acfsskrwy8hvrmaf6dvhj3 --from moderator_address ...

Proposals

The x/feepolicy module accept gov proposal for all transactions only if the moderator_address is the gov module address. Once the moderator_address is changed to EOA, gov proposals are no longer be authorized.

AnteHandlers

The x/feepolicy module provides FeeDecorators that are recursively chained together into a single Antehandler. These decorators perform basic validity checks on an Ethereum or Cosmos SDK transaction, such that it could be thrown out of the transaction Mempool.

Note that the AnteHandler is run for every transaction and called on both CheckTx and DeliverTx.

FeeDecorator

Overwrites the calculated fee decution for Cosmos-sdk transaction on the discount registered account s and msgs.