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: add fee abs module #780

Merged
merged 63 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from 50 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
cf56c42
add fee abs module
atheeshp Aug 19, 2024
5a90925
fix tests
atheeshp Aug 27, 2024
e355a38
fix tests
atheeshp Aug 27, 2024
dcf202d
fix tests
atheeshp Aug 27, 2024
291ad7f
fix tests
atheeshp Aug 27, 2024
89c3505
feat: integrated feemarket
vishal-kanna Aug 27, 2024
321ae23
add fee abs keeper in HandlerOptions
atheeshp Aug 27, 2024
5d403ad
fix tests
atheeshp Aug 28, 2024
2c0ae04
add logs
atheeshp Aug 28, 2024
defe327
chore: updated anteHandler and postHandler
vishal-kanna Aug 28, 2024
5e33e65
chore: use replace for feemarket in go.mod
vishal-kanna Aug 28, 2024
d5667f0
chore: changed go version in docker file
vishal-kanna Aug 29, 2024
8684ce9
fix : fix testing in antehandler
vishal-kanna Aug 29, 2024
ea06beb
fix: fix lint issues
vishal-kanna Aug 29, 2024
d09e816
chore: updated antehandler
vishal-kanna Aug 29, 2024
adcd9f3
fix: fix lint issues
vishal-kanna Aug 29, 2024
e2f6a74
fix: fix lint issues
vishal-kanna Aug 29, 2024
f016460
fix: lint issus
vishal-kanna Aug 29, 2024
36202e4
chore: updated ante and fix test cases
vishal-kanna Aug 30, 2024
945b3cc
fix: gofumt errors
vishal-kanna Aug 30, 2024
74089c2
fix: golint issues
vishal-kanna Aug 30, 2024
4256d7f
chore: updated postHandler
vishal-kanna Aug 30, 2024
acd8d74
testing
vishal-kanna Sep 3, 2024
4779b6a
chore: added test cases
vishal-kanna Sep 4, 2024
9557978
fix
vishal-kanna Sep 4, 2024
044bc3d
fix
vishal-kanna Sep 4, 2024
b2b8502
fix: golint issues
vishal-kanna Sep 4, 2024
e2866fb
fix : fix testcase
vishal-kanna Sep 5, 2024
9bcd0cb
fix: fix lint issues
vishal-kanna Sep 5, 2024
64c505d
disable update tests
vishal-kanna Sep 5, 2024
b05f6ee
disable report test
vishal-kanna Sep 5, 2024
9af6f82
fix: added response check in tests
vishal-kanna Sep 5, 2024
6181458
fix
vishal-kanna Sep 5, 2024
33403e1
chore: added param subsace for feemarket
vishal-kanna Sep 6, 2024
9a5c9d8
add unit tests
atheeshp Sep 6, 2024
98d86ea
fix test
atheeshp Sep 9, 2024
358cdb0
fix lint
atheeshp Sep 9, 2024
3827e97
remove comment
atheeshp Sep 9, 2024
05fa0ec
addressed review comments
vishal-kanna Sep 10, 2024
281af5e
chore: merged feemarket integration PR
vishal-kanna Sep 10, 2024
0c5a67b
fix
vishal-kanna Sep 10, 2024
1fd19a2
fix
vishal-kanna Sep 10, 2024
cb727e6
fix
vishal-kanna Sep 10, 2024
611e181
TODO in app.go
vishal-kanna Sep 10, 2024
af939e1
fix: golint error
vishal-kanna Sep 10, 2024
3bb51c1
add go mod
atheeshp Sep 11, 2024
b4c7afe
Merge branch 'vishal/integrate-antehandler' of github.com:cheqd/cheqd…
atheeshp Sep 11, 2024
999d9bb
cheqd changes
atheeshp Sep 17, 2024
2a1528a
go.mod
atheeshp Sep 17, 2024
98e903b
go mod
atheeshp Sep 17, 2024
15b751a
Temporarily disabled upgrade test runs + references
Eengineer1 Sep 18, 2024
9a64ed4
chore: added upgradeHandler and upgraded the store loader
vishal-kanna Sep 19, 2024
bd49157
Merge branch 'vishal/integrate-antehandler' of https://github.com/che…
vishal-kanna Sep 19, 2024
6ea0b87
add tests
atheeshp Sep 19, 2024
985acee
Merge branch 'vishal/integrate-antehandler' into ap/add-feeabs-mod
Eengineer1 Sep 19, 2024
1971cc2
chore: added denom resolver logic for feemarket
vishal-kanna Sep 20, 2024
5b7e733
Merge branch 'develop' into ap/add-feeabs-mod
vishal-kanna Sep 20, 2024
cf4689e
Merge branch 'develop' of https://github.com/cheqd/cheqd-node into ap…
vishal-kanna Sep 20, 2024
9d928b9
Revert "Merge branch 'develop' of https://github.com/cheqd/cheqd-node…
Eengineer1 Sep 24, 2024
4684112
Merge branch 'develop' into ap/add-feeabs-mod
Eengineer1 Sep 24, 2024
80e6c46
Temporarily disabled upgrade test suite
Eengineer1 Sep 24, 2024
1a50b17
gofumpt'ed
Eengineer1 Sep 24, 2024
23fdff8
Bump gas adjustment
Eengineer1 Sep 24, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ jobs:

- name: Combine test results
run: |
python ./.github/scripts/xml_combine.py report-unit.xml report-integration.xml report-pre-upgrade.xml report-post-upgrade.xml report-upgraded-integration.xml report-pricing-proposal.xml report-pricing-change.xml > report.xml
# python ./.github/scripts/xml_combine.py report-unit.xml report-integration.xml
# run: |
# python ./.github/scripts/xml_combine.py report-unit.xml report-integration.xml > report.xml

Expand Down
23 changes: 23 additions & 0 deletions ante/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
didtypes "github.com/cheqd/cheqd-node/x/did/types"
resourcetypes "github.com/cheqd/cheqd-node/x/resource/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
feemarkettypes "github.com/skip-mev/feemarket/x/feemarket/types"
)

type BankKeeper interface {
Expand All @@ -12,6 +14,7 @@ type BankKeeper interface {
SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error
BurnCoins(ctx sdk.Context, name string, amt sdk.Coins) error
IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error
SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
}

type DidKeeper interface {
Expand All @@ -21,3 +24,23 @@ type DidKeeper interface {
type ResourceKeeper interface {
GetParams(ctx sdk.Context) (params resourcetypes.FeeParams)
}
type AccountKeeper interface {
GetParams(ctx sdk.Context) (params authtypes.Params)
GetAccount(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
SetAccount(ctx sdk.Context, acc authtypes.AccountI)
GetModuleAddress(moduleName string) sdk.AccAddress
GetModuleAccount(ctx sdk.Context, name string) authtypes.ModuleAccountI
NewAccountWithAddress(ctx sdk.Context, addr sdk.AccAddress) authtypes.AccountI
}
type FeeGrantKeeper interface {
UseGrantedFees(ctx sdk.Context, granter, grantee sdk.AccAddress, fee sdk.Coins, msgs []sdk.Msg) error
}

type FeeMarketKeeper interface {
GetState(ctx sdk.Context) (feemarkettypes.State, error)
GetMinGasPrice(ctx sdk.Context, denom string) (sdk.DecCoin, error)
GetParams(ctx sdk.Context) (feemarkettypes.Params, error)
SetState(ctx sdk.Context, state feemarkettypes.State) error
SetParams(ctx sdk.Context, params feemarkettypes.Params) error
ResolveToDenom(ctx sdk.Context, coin sdk.DecCoin, denom string) (sdk.DecCoin, error)
}
183 changes: 49 additions & 134 deletions ante/fee.go
Original file line number Diff line number Diff line change
@@ -1,43 +1,24 @@
package ante

import (
"fmt"

"github.com/cosmos/cosmos-sdk/types/errors"

errorsmod "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)

type TxFeeChecker func(ctx sdk.Context, tx sdk.Tx) (sdk.Coins, int64, error)

// DeductFeeDecorator deducts fees from the first signer of the tx
// If the first signer does not have the funds to pay for the fees, return with InsufficientFunds error
// Call next AnteHandler if fees successfully deducted
// CONTRACT: Tx must implement FeeTx interface to use DeductFeeDecorator
type DeductFeeDecorator struct {
accountKeeper ante.AccountKeeper
bankKeeper BankKeeper
feegrantKeeper ante.FeegrantKeeper
txFeeChecker TxFeeChecker
type OverAllDecorator struct {
decorators []sdk.AnteDecorator
}

func NewDeductFeeDecorator(ak ante.AccountKeeper, bk BankKeeper, fk ante.FeegrantKeeper, tfc TxFeeChecker) DeductFeeDecorator {
if tfc == nil {
tfc = checkTxFeeWithValidatorMinGasPrices
}

return DeductFeeDecorator{
accountKeeper: ak,
bankKeeper: bk,
feegrantKeeper: fk,
txFeeChecker: tfc,
func NewOverAllDecorator(decorators ...sdk.AnteDecorator) OverAllDecorator {
return OverAllDecorator{
decorators: decorators,
}
}

func (dfd DeductFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
func (dfd OverAllDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) {
feeTx, ok := tx.(sdk.FeeTx)
if !ok {
return ctx, errorsmod.Wrap(errors.ErrTxDecode, "Tx must be a FeeTx")
Expand All @@ -51,9 +32,6 @@ func (dfd DeductFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bo
priority int64
err error
)

fee := feeTx.GetFee()

// check if the tx is a taxable tx
// CONTRACT: Taxable tx is a tx that has at least 1 taxable related Msg.
taxable := IsTaxableTxLite(tx)
Expand All @@ -65,118 +43,55 @@ func (dfd DeductFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bo
return next(newCtx, tx, simulate)
}

// if not taxable, follow default
if !simulate {
fee, priority, err = dfd.txFeeChecker(ctx, tx)
if err != nil {
return ctx, err
}
}
if err := dfd.checkDeductFee(ctx, tx, fee); err != nil {
return ctx, err
handler := sdk.ChainAnteDecorators(dfd.decorators...)
newCtx, err := handler(ctx, tx, simulate)
if err != nil {
return newCtx, err
}

newCtx := ctx.WithPriority(priority)

return next(newCtx, tx, simulate)
}

func (dfd DeductFeeDecorator) checkDeductFee(ctx sdk.Context, sdkTx sdk.Tx, fee sdk.Coins) error {
feeTx, ok := sdkTx.(sdk.FeeTx)
if !ok {
return errorsmod.Wrap(errors.ErrTxDecode, "Tx must be a FeeTx")
}

if addr := dfd.accountKeeper.GetModuleAddress(types.FeeCollectorName); addr == nil {
return fmt.Errorf("fee collector module account (%s) has not been set", types.FeeCollectorName)
}

feePayer := feeTx.FeePayer()
feeGranter := feeTx.FeeGranter()
deductFeesFrom := feePayer

// if feegranter set deduct fee from feegranter account.
// this works with only when feegrant enabled.
if feeGranter != nil {
if dfd.feegrantKeeper == nil {
return errors.ErrInvalidRequest.Wrap("fee grants are not enabled")
} else if !feeGranter.Equals(feePayer) {
err := dfd.feegrantKeeper.UseGrantedFees(ctx, feeGranter, feePayer, fee, sdkTx.GetMsgs())
if err != nil {
return errorsmod.Wrapf(err, "%s does not not allow to pay fees for %s", feeGranter, feePayer)
}
}

deductFeesFrom = feeGranter
}

deductFeesFromAcc := dfd.accountKeeper.GetAccount(ctx, deductFeesFrom)
if deductFeesFromAcc == nil {
return errors.ErrUnknownAddress.Wrapf("fee payer address: %s does not exist", deductFeesFrom)
}

// deduct the fees
if !fee.IsZero() {
err := DeductFees(dfd.bankKeeper, ctx, deductFeesFromAcc, fee)
if err != nil {
return err
// CheckTxFee implements the logic for the fee market to check if a Tx has provided sufficient
// fees given the current state of the fee market. Returns an error if insufficient fees.
func CheckTxFee(ctx sdk.Context, gasPrice sdk.DecCoin, feeCoin sdk.Coin, feeGas int64, isAnte bool) (payCoin sdk.Coin, tip sdk.Coin, err error) {
payCoin = feeCoin
// Ensure that the provided fees meet the minimum
if !gasPrice.IsZero() {
var (
requiredFee sdk.Coin
consumedFee sdk.Coin
)

// Determine the required fees by multiplying each required minimum gas
// price by the gas, where fee = ceil(minGasPrice * gas).
gasConsumed := int64(ctx.GasMeter().GasConsumed())
gcDec := sdkmath.LegacyNewDec(gasConsumed)
glDec := sdkmath.LegacyNewDec(feeGas)

consumedFeeAmount := gasPrice.Amount.Mul(gcDec)
limitFee := gasPrice.Amount.Mul(glDec)

consumedFee = sdk.NewCoin(gasPrice.Denom, consumedFeeAmount.Ceil().RoundInt())
requiredFee = sdk.NewCoin(gasPrice.Denom, limitFee.Ceil().RoundInt())

if !payCoin.IsGTE(requiredFee) {
return sdk.Coin{}, sdk.Coin{}, errors.ErrInsufficientFee.Wrapf(
"got: %s required: %s, minGasPrice: %s, gas: %d",
payCoin,
requiredFee,
gasPrice,
gasConsumed,
)
}
}

events := sdk.Events{
sdk.NewEvent(
sdk.EventTypeTx,
sdk.NewAttribute(sdk.AttributeKeyFee, fee.String()),
sdk.NewAttribute(sdk.AttributeKeyFeePayer, deductFeesFrom.String()),
),
}
ctx.EventManager().EmitEvents(events)

return nil
}

// DeductFees deducts fees from the given account.
func DeductFees(bankKeeper types.BankKeeper, ctx sdk.Context, acc types.AccountI, fees sdk.Coins) error {
if !fees.IsValid() {
return errorsmod.Wrapf(errors.ErrInsufficientFee, "invalid fee amount: %s", fees)
}

err := bankKeeper.SendCoinsFromAccountToModule(ctx, acc.GetAddress(), types.FeeCollectorName, fees)
if err != nil {
return errorsmod.Wrapf(errors.ErrInsufficientFunds, err.Error())
}

return nil
}

func IsSufficientFee(ctx sdk.Context, tax, reward, burn, feeProvided sdk.Coins, gasRequested int64) (bool, int64, error) {
// check if the provided fee is enough for `did`, `resource` module specific Msg
if !feeProvided.IsAnyGTE(tax) {
return false, 0, errorsmod.Wrapf(errors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", feeProvided, tax)
}

// check with the default validator min gas prices based on rewards distribution
if ctx.IsCheckTx() {
minGasPrices := ctx.MinGasPrices()
if !minGasPrices.IsZero() {
requiredFees := make(sdk.Coins, len(minGasPrices))

// Determine the required fees by multiplying each required minimum gas
// price by the gas limit, where fee = ceil(minGasPrice * gasLimit).
glDec := sdk.NewDec(gasRequested)
for i, gp := range minGasPrices {
fee := gp.Amount.Mul(glDec)
requiredFees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt())
}

// check if the fee is sufficient
if !reward.IsAnyGTE(requiredFees) {
return false, 0, errorsmod.Wrapf(errors.ErrInsufficientFee, "insufficient fees; got: %s required: %s", reward, requiredFees)
}
if isAnte {
tip = payCoin.Sub(requiredFee)
payCoin = requiredFee
} else {
tip = payCoin.Sub(consumedFee)
payCoin = consumedFee
}
}

priority := getTxPriority(tax, gasRequested)

return true, priority, nil
return payCoin, tip, nil
}
Loading
Loading