Skip to content

Commit

Permalink
feat!: Introduce feemarket module (#3028)
Browse files Browse the repository at this point in the history
* Added feemarket module

Co-authored-by: Dusan Maksimovic <dusan.maksimovic@ethernal.tech>

* Added blocksdk support

Co-authored-by: Dusan Maksimovic <dusan.maksimovic@ethernal.tech>

* Removed globalfee from app

Co-authored-by: Dusan Maksimovic <dusan.maksimovic@ethernal.tech>

* Cleanup and lint fix

Co-authored-by: Dusan Maksimovic <dusan.maksimovic@ethernal.tech>

* added post-handler and test for feemarket

Co-authored-by: Stana Miric <stana.miric@ethernal.tech>

* tests fix part 1

Co-authored-by: Dusan Maksimovic <dusan.maksimovic@ethernal.tech>

* test fix part 2
Co-authored-by: Dusan Maksimovic <dusan.maksimovic@ethernal.tech>

* added changelog
Co-authored-by: Dusan Maksimovic <dusan.maksimovic@ethernal.tech>

* update x/feemarket dependency

* fix broken dep update for feemarket

* Fixed merge errors & unit tests

Co-authored-by: Stana Miric <stana.miric@ethernal.tech>

* Removed Skip Block SDK

Co-authored-by: Stana Miric <stana.miric@ethernal.tech>

* set upgrade params and test fixes

* fix e2e tests & cleanup

* merge fix

* globalfee module removed from the repository

* simplify the check for expected user balances in e2e tests

* upgrade to a new version of the feemarket & minimum fees enforcement if feemarket is disabled

* deps: bump feemarket v1.0.2-sdk47; bump hermes v1.9.0

* scripts: update hermes configs

* update changelogs (depr x/globalfee)

* e2e: change sequence on validator genesis acc

* e2e: mv hermes calls in ibc_tests

* e2e: adjust gas in staking ops

* e2e: mv extension tests; update feegrant tests

* deps: bump feemarket v1.0.3-sdk47

* Update .changelog/unreleased/features/3028-add-feemarket

Co-authored-by: Marius Poke <marius.poke@posteo.de>

* Update .changelog/unreleased/state-breaking/3028-add-feemarket

Co-authored-by: Marius Poke <marius.poke@posteo.de>

* update changelogs

---------

Co-authored-by: Dusan Maksimovic <dusan.maksimovic@ethernal.tech>
Co-authored-by: MSalopek <matija.salopek994@gmail.com>
Co-authored-by: Marius Poke <marius.poke@posteo.de>
  • Loading branch information
4 people committed Jun 18, 2024
1 parent f6b45e2 commit 2758025
Show file tree
Hide file tree
Showing 73 changed files with 1,273 additions and 5,398 deletions.
1 change: 0 additions & 1 deletion .changelog/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,5 @@ entry_indent = 2
# to Markdown) and a path relative to the project folder (i.e. relative to
# the parent of the `.changelog` folder).
[components.all]
globalfee = { name = "GlobalFee", path = "x/globalfee" }
tests = { name = "Tests", path = "tests" }
docs = { name = "Documentation", path = "docs" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- Add feemarket module
- Remove globalfee module from the app and repository
- Remove auth module 'DeductFeeDecorator'
- Remove x/globalfee module
([\#3028](https://github.com/cosmos/gaia/pull/3028))
2 changes: 2 additions & 0 deletions .changelog/unreleased/dependencies/3028-bump-go.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Bump go version to 1.22
([\#3028](https://github.com/cosmos/gaia/pull/3028))
2 changes: 2 additions & 0 deletions .changelog/unreleased/features/3028-add-feemarket.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Add the feemarket module. Remove the auth module 'DeductFeeDecorator'.
([\#3028](https://github.com/cosmos/gaia/pull/3028))
2 changes: 2 additions & 0 deletions .changelog/unreleased/state-breaking/3028-add-feemarket.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Add the feemarket module. Remove the globalfee module from the app and repository. Remove the auth module 'DeductFeeDecorator'.
([\#3028](https://github.com/cosmos/gaia/pull/3028))
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- Add feemarket module
- Remove globalfee module from the app and repository
- Remove auth module 'DeductFeeDecorator'
- Remove x/globalfee module
([\#3028](https://github.com/cosmos/gaia/pull/3028))
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ where:
not necessarily with the same `short-description` or content;
- `pr-number` is the PR number;
- `short-description` is a short (4 to 6 word), hyphen separated description of the change;
- `component` is used for changes that affect one of the components defined in the [config](.changelog/config.toml), e.g., `tests`, `globalfee`.
- `component` is used for changes that affect one of the components defined in the [config](.changelog/config.toml), e.g., `tests`, `docs`.
For examples, see the [.changelog](.changelog) folder.
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ BUILDDIR ?= $(CURDIR)/build
TEST_DOCKER_REPO=cosmos/contrib-gaiatest

GO_SYSTEM_VERSION = $(shell go version | cut -c 14- | cut -d' ' -f1 | cut -d'.' -f1-2)
REQUIRE_GO_VERSION = 1.21
REQUIRE_GO_VERSION = 1.22

export GO111MODULE = on

Expand Down
36 changes: 24 additions & 12 deletions ante/ante.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package ante

import (
feemarketante "github.com/skip-mev/feemarket/x/feemarket/ante"
feemarketkeeper "github.com/skip-mev/feemarket/x/feemarket/keeper"

ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante"
ibckeeper "github.com/cosmos/ibc-go/v7/modules/core/keeper"

Expand All @@ -9,22 +12,23 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"

gaiaerrors "github.com/cosmos/gaia/v18/types/errors"
gaiafeeante "github.com/cosmos/gaia/v18/x/globalfee/ante"
)

// UseFeeMarketDecorator to make the integration testing easier: we can switch off its ante and post decorators with this flag
var UseFeeMarketDecorator = true

// HandlerOptions extend the SDK's AnteHandler options by requiring the IBC
// channel keeper.
type HandlerOptions struct {
ante.HandlerOptions
Codec codec.BinaryCodec
IBCkeeper *ibckeeper.Keeper
GlobalFeeSubspace paramtypes.Subspace
StakingKeeper *stakingkeeper.Keeper
TxFeeChecker ante.TxFeeChecker
Codec codec.BinaryCodec
IBCkeeper *ibckeeper.Keeper
StakingKeeper *stakingkeeper.Keeper
FeeMarketKeeper *feemarketkeeper.Keeper
TxFeeChecker ante.TxFeeChecker
}

func NewAnteHandler(opts HandlerOptions) (sdk.AnteHandler, error) {
Expand All @@ -40,9 +44,8 @@ func NewAnteHandler(opts HandlerOptions) (sdk.AnteHandler, error) {
if opts.IBCkeeper == nil {
return nil, errorsmod.Wrap(gaiaerrors.ErrLogic, "IBC keeper is required for AnteHandler")
}

if opts.GlobalFeeSubspace.Name() == "" {
return nil, errorsmod.Wrap(gaiaerrors.ErrNotFound, "globalfee param store is required for AnteHandler")
if opts.FeeMarketKeeper == nil {
return nil, errorsmod.Wrap(gaiaerrors.ErrLogic, "FeeMarket keeper is required for AnteHandler")
}

if opts.StakingKeeper == nil {
Expand All @@ -62,8 +65,6 @@ func NewAnteHandler(opts HandlerOptions) (sdk.AnteHandler, error) {
ante.NewValidateMemoDecorator(opts.AccountKeeper),
ante.NewConsumeGasForTxSizeDecorator(opts.AccountKeeper),
NewGovVoteDecorator(opts.Codec, opts.StakingKeeper),
gaiafeeante.NewFeeDecorator(opts.GlobalFeeSubspace, opts.StakingKeeper),
ante.NewDeductFeeDecorator(opts.AccountKeeper, opts.BankKeeper, opts.FeegrantKeeper, opts.TxFeeChecker),
ante.NewSetPubKeyDecorator(opts.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators
ante.NewValidateSigCountDecorator(opts.AccountKeeper),
ante.NewSigGasConsumeDecorator(opts.AccountKeeper, sigGasConsumer),
Expand All @@ -72,5 +73,16 @@ func NewAnteHandler(opts HandlerOptions) (sdk.AnteHandler, error) {
ibcante.NewRedundantRelayDecorator(opts.IBCkeeper),
}

if UseFeeMarketDecorator {
anteDecorators = append(anteDecorators,
feemarketante.NewFeeMarketCheckDecorator(
opts.FeeMarketKeeper,
ante.NewDeductFeeDecorator(
opts.AccountKeeper,
opts.BankKeeper,
opts.FeegrantKeeper,
opts.TxFeeChecker)))
}

return sdk.ChainAnteDecorators(anteDecorators...), nil
}
64 changes: 53 additions & 11 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/gorilla/mux"
"github.com/rakyll/statik/fs"
feemarketkeeper "github.com/skip-mev/feemarket/x/feemarket/keeper"
"github.com/spf13/cast"

// unnamed import of statik for swagger UI support
Expand Down Expand Up @@ -56,7 +57,6 @@ import (
"github.com/cosmos/gaia/v18/app/params"
"github.com/cosmos/gaia/v18/app/upgrades"
v18 "github.com/cosmos/gaia/v18/app/upgrades/v18"
"github.com/cosmos/gaia/v18/x/globalfee"
)

var (
Expand Down Expand Up @@ -223,20 +223,34 @@ func NewGaiaApp(
SignModeHandler: encodingConfig.TxConfig.SignModeHandler(),
SigGasConsumer: ante.DefaultSigVerificationGasConsumer,
},
Codec: appCodec,
IBCkeeper: app.IBCKeeper,
GlobalFeeSubspace: app.GetSubspace(globalfee.ModuleName),
StakingKeeper: app.StakingKeeper,
// If TxFeeChecker is nil the default ante TxFeeChecker is used
// so we use this no-op to keep the global fee module behaviour unchanged
TxFeeChecker: noOpTxFeeChecker,
Codec: appCodec,
IBCkeeper: app.IBCKeeper,
StakingKeeper: app.StakingKeeper,
FeeMarketKeeper: app.FeeMarketKeeper,
TxFeeChecker: func(ctx sdk.Context, tx sdk.Tx) (sdk.Coins, int64, error) {
return minTxFeesChecker(ctx, tx, *app.FeeMarketKeeper)
},
},
)
if err != nil {
panic(fmt.Errorf("failed to create AnteHandler: %s", err))
}

postHandlerOptions := PostHandlerOptions{
AccountKeeper: app.AccountKeeper,
BankKeeper: app.BankKeeper,
FeeGrantKeeper: app.FeeGrantKeeper,
FeeMarketKeeper: app.FeeMarketKeeper,
}
postHandler, err := NewPostHandler(postHandlerOptions)
if err != nil {
panic(err)
}

// set ante and post handlers
app.SetAnteHandler(anteHandler)
app.SetPostHandler(postHandler)

app.SetInitChainer(app.InitChainer)
app.SetBeginBlocker(app.BeginBlocker)
app.SetEndBlocker(app.EndBlocker)
Expand Down Expand Up @@ -442,13 +456,41 @@ func (ao EmptyAppOptions) Get(_ string) interface{} {
return nil
}

// noOpTxFeeChecker is an ante TxFeeChecker for the DeductFeeDecorator, see x/auth/ante/fee.go,
// it performs a no-op by not checking tx fees and always returns a zero tx priority
func noOpTxFeeChecker(_ sdk.Context, tx sdk.Tx) (sdk.Coins, int64, error) {
// minTxFeesChecker will be executed only if the feemarket module is disabled.
// In this case, the auth module's DeductFeeDecorator is executed, and
// we use the minTxFeesChecker to enforce the minimum transaction fees.
// Min tx fees are calculated as gas_limit * feemarket_min_base_gas_price
func minTxFeesChecker(ctx sdk.Context, tx sdk.Tx, feemarketKp feemarketkeeper.Keeper) (sdk.Coins, int64, error) {
feeTx, ok := tx.(sdk.FeeTx)
if !ok {
return nil, 0, errorsmod.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx")
}

// To keep the gentxs with zero fees, we need to skip the validation in the first block
if ctx.BlockHeight() == 0 {
return feeTx.GetFee(), 0, nil
}

feeMarketParams, err := feemarketKp.GetParams(ctx)
if err != nil {
return nil, 0, err
}

feeRequired := sdk.NewCoins(
sdk.NewCoin(
feeMarketParams.FeeDenom,
feeMarketParams.MinBaseGasPrice.MulInt(sdk.NewIntFromUint64(feeTx.GetGas())).Ceil().RoundInt()))

feeCoins := feeTx.GetFee()
if len(feeCoins) != 1 {
return nil, 0, fmt.Errorf(
"expected exactly one fee coin; got %s, required: %s", feeCoins.String(), feeRequired.String())
}

if !feeCoins.IsAnyGTE(feeRequired) {
return nil, 0, fmt.Errorf(
"not enough fees provided; got %s, required: %s", feeCoins.String(), feeRequired.String())
}

return feeTx.GetFee(), 0, nil
}
29 changes: 26 additions & 3 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package keepers

import (
"fmt"
"os"

ratelimit "github.com/Stride-Labs/ibc-rate-limiting/ratelimit"
ratelimitkeeper "github.com/Stride-Labs/ibc-rate-limiting/ratelimit/keeper"
ratelimittypes "github.com/Stride-Labs/ibc-rate-limiting/ratelimit/types"
feemarketkeeper "github.com/skip-mev/feemarket/x/feemarket/keeper"
feemarkettypes "github.com/skip-mev/feemarket/x/feemarket/types"

// unnamed import of statik for swagger UI support
_ "github.com/cosmos/cosmos-sdk/client/docs/statik"
Expand Down Expand Up @@ -77,8 +80,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/upgrade"
upgradekeeper "github.com/cosmos/cosmos-sdk/x/upgrade/keeper"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"

"github.com/cosmos/gaia/v18/x/globalfee"
)

type AppKeepers struct {
Expand Down Expand Up @@ -108,6 +109,7 @@ type AppKeepers struct {
FeeGrantKeeper feegrantkeeper.Keeper
AuthzKeeper authzkeeper.Keeper
ConsensusParamsKeeper consensusparamkeeper.Keeper
FeeMarketKeeper *feemarketkeeper.Keeper

// ICS
ProviderKeeper icsproviderkeeper.Keeper
Expand Down Expand Up @@ -278,6 +280,14 @@ func NewAppKeeper(
),
)

appKeepers.FeeMarketKeeper = feemarketkeeper.NewKeeper(
appCodec,
appKeepers.keys[feemarkettypes.StoreKey],
appKeepers.AccountKeeper,
&DefaultFeemarketDenomResolver{},
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

// UpgradeKeeper must be created before IBCKeeper
appKeepers.UpgradeKeeper = upgradekeeper.NewKeeper(
skipUpgradeHeights,
Expand Down Expand Up @@ -514,8 +524,21 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino
paramsKeeper.Subspace(icacontrollertypes.SubModuleName)
paramsKeeper.Subspace(pfmroutertypes.ModuleName).WithKeyTable(pfmroutertypes.ParamKeyTable())
paramsKeeper.Subspace(ratelimittypes.ModuleName)
paramsKeeper.Subspace(globalfee.ModuleName)
paramsKeeper.Subspace(providertypes.ModuleName)

return paramsKeeper
}

type DefaultFeemarketDenomResolver struct{}

func (r *DefaultFeemarketDenomResolver) ConvertToDenom(_ sdk.Context, coin sdk.DecCoin, denom string) (sdk.DecCoin, error) {
if coin.Denom == denom {
return coin, nil
}

return sdk.DecCoin{}, fmt.Errorf("error resolving denom")
}

func (r *DefaultFeemarketDenomResolver) ExtraDenoms(_ sdk.Context) ([]string, error) {
return []string{}, nil
}
2 changes: 2 additions & 0 deletions app/keepers/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keepers

import (
ratelimittypes "github.com/Stride-Labs/ibc-rate-limiting/ratelimit/types"
feemarkettypes "github.com/skip-mev/feemarket/x/feemarket/types"

routertypes "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v7/packetforward/types"
icacontrollertypes "github.com/cosmos/ibc-go/v7/modules/apps/27-interchain-accounts/controller/types"
Expand Down Expand Up @@ -57,6 +58,7 @@ func (appKeepers *AppKeepers) GenerateKeys() {
ratelimittypes.StoreKey,
providertypes.StoreKey,
consensusparamtypes.StoreKey,
feemarkettypes.StoreKey,
)

// Define transient store keys
Expand Down
Loading

0 comments on commit 2758025

Please sign in to comment.