Skip to content

Commit

Permalink
Allow to paid by multiple fees denom
Browse files Browse the repository at this point in the history
  • Loading branch information
phamminh0811 committed Jul 16, 2024
1 parent a16d4df commit ed0ad82
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 174 deletions.
8 changes: 4 additions & 4 deletions custom/auth/ante/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import (
dyncommante "github.com/classic-terra/core/v3/x/dyncomm/ante"
dyncommkeeper "github.com/classic-terra/core/v3/x/dyncomm/keeper"
tax2gasante "github.com/classic-terra/core/v3/x/tax2gas/ante"

tax2gasKeeper "github.com/classic-terra/core/v3/x/tax2gas/keeper"
tax2gaskeeper "github.com/classic-terra/core/v3/x/tax2gas/keeper"
tax2gastypes "github.com/classic-terra/core/v3/x/tax2gas/types"
"github.com/cosmos/cosmos-sdk/codec"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
ibcante "github.com/cosmos/ibc-go/v7/modules/core/ante"
Expand All @@ -29,7 +29,7 @@ type HandlerOptions struct {
AccountKeeper ante.AccountKeeper
BankKeeper BankKeeper
ExtensionOptionChecker ante.ExtensionOptionChecker
FeegrantKeeper ante.FeegrantKeeper
FeegrantKeeper tax2gastypes.FeegrantKeeper
OracleKeeper OracleKeeper
TreasuryKeeper TreasuryKeeper
SignModeHandler signing.SignModeHandler
Expand All @@ -43,7 +43,7 @@ type HandlerOptions struct {
TXCounterStoreKey storetypes.StoreKey
DyncommKeeper dyncommkeeper.Keeper
StakingKeeper *stakingkeeper.Keeper
Tax2Gaskeeper tax2gasKeeper.Keeper
Tax2Gaskeeper tax2gaskeeper.Keeper
Cdc codec.BinaryCodec
}

Expand Down
1 change: 1 addition & 0 deletions custom/auth/ante/expected_keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type OracleKeeper interface {

// BankKeeper defines the contract needed for supply related APIs (noalias)
type BankKeeper interface {
GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin
IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error
SendCoins(ctx sdk.Context, from, to sdk.AccAddress, amt sdk.Coins) error
SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error
Expand Down
20 changes: 10 additions & 10 deletions custom/wasm/keeper/handler_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@ import (
"regexp"
"strings"

marketexported "github.com/classic-terra/core/v3/x/market/exported"
"github.com/classic-terra/core/v3/x/tax2gas/types"
treasurykeeper "github.com/classic-terra/core/v3/x/treasury/keeper"

errorsmod "cosmossdk.io/errors"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"
"github.com/cosmos/cosmos-sdk/baseapp"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -22,6 +17,11 @@ import (

wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
wasmvmtypes "github.com/CosmWasm/wasmvm/types"

marketexported "github.com/classic-terra/core/v3/x/market/exported"
"github.com/classic-terra/core/v3/x/tax2gas/types"
treasurykeeper "github.com/classic-terra/core/v3/x/treasury/keeper"
)

// msgEncoder is an extension point to customize encodings
Expand Down Expand Up @@ -83,10 +83,10 @@ func (h SDKMessageHandler) DispatchMsg(ctx sdk.Context, contractAddr sdk.AccAddr
return nil, nil, err
}

tx_origin := ctx.Value(wasmtypes.TxOrigin)
feePayer, ok := tx_origin.(sdk.AccAddress)
txOrigin := ctx.Value(wasmtypes.TxOrigin)
feePayer, ok := txOrigin.(sdk.AccAddress)
if !ok {
return nil, nil, errorsmod.Wrap(sdkerrors.ErrTxDecode, "tx_origin is not a valid")
return nil, nil, errorsmod.Wrap(sdkerrors.ErrTxDecode, "tx_origin is not valid")
}
for _, sdkMsg := range sdkMsgs {
taxes := FilterMsgAndComputeTax(ctx, h.treasuryKeeper, sdkMsg)
Expand Down Expand Up @@ -124,7 +124,7 @@ func (h SDKMessageHandler) handleSdkMessage(ctx sdk.Context, contractAddr sdk.Ad
// make sure this account can send it
for _, acct := range msg.GetSigners() {
if !acct.Equals(contractAddr) {
return nil, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "contract doesn't have permission")
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "contract doesn't have permission")
}
}

Expand All @@ -139,7 +139,7 @@ func (h SDKMessageHandler) handleSdkMessage(ctx sdk.Context, contractAddr sdk.Ad
// proto messages and has registered all `Msg services`, then this
// path should never be called, because all those Msgs should be
// registered within the `msgServiceRouter` already.
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "can't route message %+v", msg)
return nil, errorsmod.Wrapf(sdkerrors.ErrUnknownRequest, "can't route message %+v", msg)
}

var IBCRegexp = regexp.MustCompile("^ibc/[a-fA-F0-9]{64}$")
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require (
cosmossdk.io/math v1.3.0
cosmossdk.io/simapp v0.0.0-20230602123434-616841b9704d
github.com/CosmWasm/wasmd v0.45.0
github.com/CosmWasm/wasmvm v1.5.0
github.com/CosmWasm/wasmvm v1.5.2
github.com/cometbft/cometbft v0.37.4
github.com/cometbft/cometbft-db v0.8.0
github.com/cosmos/cosmos-sdk v0.47.10
Expand Down Expand Up @@ -225,7 +225,7 @@ replace (
)

replace (
github.com/CosmWasm/wasmd => github.com/classic-terra/wasmd v0.45.0-terra.3
github.com/CosmWasm/wasmd => github.com/classic-terra/wasmd v0.45.1-0.20240716075902-ce9c9cb9b363
// use cometbft
github.com/cometbft/cometbft => github.com/classic-terra/cometbft v0.37.4-terra1
github.com/cometbft/cometbft-db => github.com/cometbft/cometbft-db v0.8.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,8 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg6
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/ChainSafe/go-schnorrkel v1.0.0 h1:3aDA67lAykLaG1y3AOjs88dMxC88PgUuHRrLeDnvGIM=
github.com/ChainSafe/go-schnorrkel v1.0.0/go.mod h1:dpzHYVxLZcp8pjlV+O+UR8K0Hp/z7vcchBSbMBEhCw4=
github.com/CosmWasm/wasmvm v1.5.0 h1:3hKeT9SfwfLhxTGKH3vXaKFzBz1yuvP8SlfwfQXbQfw=
github.com/CosmWasm/wasmvm v1.5.0/go.mod h1:fXB+m2gyh4v9839zlIXdMZGeLAxqUdYdFQqYsTha2hc=
github.com/CosmWasm/wasmvm v1.5.2 h1:+pKB1Mz9GZVt1vadxB+EDdD1FOz3dMNjIKq/58/lrag=
github.com/CosmWasm/wasmvm v1.5.2/go.mod h1:Q0bSEtlktzh7W2hhEaifrFp1Erx11ckQZmjq8FLCyys=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
Expand Down Expand Up @@ -356,8 +356,8 @@ github.com/classic-terra/goleveldb v0.0.0-20230914223247-2b28f6655121 h1:fjpWDB0
github.com/classic-terra/goleveldb v0.0.0-20230914223247-2b28f6655121/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc=
github.com/classic-terra/ibc-go/v7 v7.4.0-terra h1:hawaq62XKlxyc8xLyIcc6IujDDEbqDBU+2U15SF+hj8=
github.com/classic-terra/ibc-go/v7 v7.4.0-terra/go.mod h1:s0lxNkjVIqsb8AVltL0qhzxeLgOKvWZrknPuvgjlEQ8=
github.com/classic-terra/wasmd v0.45.0-terra.3 h1:Fpjrjco0ig4dLwX6KrT+z0Zjo2iJCggM2X0JppyA/ko=
github.com/classic-terra/wasmd v0.45.0-terra.3/go.mod h1:pTPOut260rZ3J0WROheOgNWDV/vk/AeRdXmM1JOtMjk=
github.com/classic-terra/wasmd v0.45.1-0.20240716075902-ce9c9cb9b363 h1:z6qheMvuS9Uongc5obQQbL0hmiJ7s5MKHfYgJl4BQeU=
github.com/classic-terra/wasmd v0.45.1-0.20240716075902-ce9c9cb9b363/go.mod h1:cdb31ecSxIQrq/ZmYf9KYNbsdqbHfFUUGiA2dHeYxsA=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
Expand Down
84 changes: 53 additions & 31 deletions x/tax2gas/ante/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (

tax2gasKeeper "github.com/classic-terra/core/v3/x/tax2gas/keeper"
"github.com/classic-terra/core/v3/x/tax2gas/types"
tax2gasUtils "github.com/classic-terra/core/v3/x/tax2gas/utils"
tax2gasutils "github.com/classic-terra/core/v3/x/tax2gas/utils"
)

// FeeDecorator deducts fees from the first signer of the tx
Expand All @@ -22,12 +22,12 @@ import (
type FeeDecorator struct {
accountKeeper ante.AccountKeeper
bankKeeper types.BankKeeper
feegrantKeeper ante.FeegrantKeeper
feegrantKeeper types.FeegrantKeeper
treasuryKeeper types.TreasuryKeeper
tax2gasKeeper tax2gasKeeper.Keeper
}

func NewFeeDecorator(ak ante.AccountKeeper, bk types.BankKeeper, fk ante.FeegrantKeeper, tk types.TreasuryKeeper, taxKeeper tax2gasKeeper.Keeper) FeeDecorator {
func NewFeeDecorator(ak ante.AccountKeeper, bk types.BankKeeper, fk types.FeegrantKeeper, tk types.TreasuryKeeper, taxKeeper tax2gasKeeper.Keeper) FeeDecorator {
return FeeDecorator{
accountKeeper: ak,
bankKeeper: bk,
Expand All @@ -53,22 +53,22 @@ func (fd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, nex
)

msgs := feeTx.GetMsgs()
if tax2gasUtils.IsOracleTx(msgs) {
if tax2gasutils.IsOracleTx(msgs) {
return next(ctx, tx, simulate)
}

// Compute taxes based on consumed gas
gasPrices := fd.tax2gasKeeper.GetGasPrices(ctx)
gasConsumed := ctx.GasMeter().GasConsumed()
gasConsumedTax, err := tax2gasUtils.ComputeTaxOnGasConsumed(ctx, tx, gasPrices, gasConsumed)
gasConsumedFees, err := tax2gasutils.ComputeFeesOnGasConsumed(ctx, tx, gasPrices, gasConsumed)
if err != nil {
return ctx, err
}

// Compute taxes based on sent amount
taxes := tax2gasUtils.FilterMsgAndComputeTax(ctx, fd.treasuryKeeper, msgs...)
taxes := tax2gasutils.FilterMsgAndComputeTax(ctx, fd.treasuryKeeper, msgs...)
// Convert taxes to gas
taxGas, err := tax2gasUtils.ComputeGas(ctx, tx, gasPrices, taxes)
taxGas, err := tax2gasutils.ComputeGas(ctx, tx, gasPrices, taxes)
if err != nil {
return ctx, err
}
Expand All @@ -78,15 +78,15 @@ func (fd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, nex
}

if !simulate && !taxes.IsZero() {
// Fee has to at least be enough to cover taxes + gasConsumedTax
priority, err = fd.checkTxFee(ctx, tx, gasConsumedTax.Add(taxes...))
// Fee has to at least be enough to cover taxes + gasConsumedFees
priority, err = fd.checkTxFee(ctx, tx, gasConsumedFees.Add(taxes...))
if err != nil {
return ctx, err
}
}

// Try to deduct the gasConsumed tax
feeDenom, err := fd.checkDeductFee(ctx, feeTx, gasConsumedTax, simulate)
// Try to deduct the gasConsumed fees
paidDenom, err := fd.checkDeductFee(ctx, feeTx, gasConsumedFees, simulate)
if err != nil {
return ctx, err
}
Expand All @@ -95,12 +95,11 @@ func (fd FeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, nex
if taxGas != 0 {
newCtx = newCtx.WithValue(types.TaxGas, taxGas)
}
if !gasConsumedTax.IsZero() {
newCtx = newCtx.WithValue(types.ConsumedGasFee, gasConsumedTax)
}
if feeDenom != "" {
newCtx = newCtx.WithValue(types.FeeDenom, feeDenom)
newCtx = newCtx.WithValue(types.AnteConsumedGas, gasConsumed)
if paidDenom != "" {
newCtx = newCtx.WithValue(types.PaidDenom, paidDenom)
}

return next(newCtx, tx, simulate)
}

Expand All @@ -114,16 +113,15 @@ func (fd FeeDecorator) checkDeductFee(ctx sdk.Context, feeTx sdk.FeeTx, taxes sd
feeGranter := feeTx.FeeGranter()
deductFeesFrom := feePayer

var foundCoins sdk.Coins

foundCoins := sdk.Coins{}
if !taxes.IsZero() {
for _, coin := range feeCoins {
found, requiredFee := taxes.Find(coin.Denom)
if !found {
continue
}
if coin.Amount.GT(requiredFee.Amount) {
foundCoins = sdk.NewCoins(requiredFee)
foundCoins = foundCoins.Add(requiredFee)
}
}
} else {
Expand All @@ -136,9 +134,27 @@ func (fd FeeDecorator) checkDeductFee(ctx sdk.Context, feeTx sdk.FeeTx, taxes sd
if fd.feegrantKeeper == nil {
return "", sdkerrors.ErrInvalidRequest.Wrap("fee grants are not enabled")
} else if !feeGranter.Equals(feePayer) {
err := fd.feegrantKeeper.UseGrantedFees(ctx, feeGranter, feePayer, foundCoins, feeTx.GetMsgs())
allowance, err := fd.feegrantKeeper.GetAllowance(ctx, feeGranter, feePayer)
if err != nil {
return "", errorsmod.Wrapf(err, "%s does not not allow to pay fees for %s", feeGranter, feePayer)
return "", errorsmod.Wrapf(err, "fee-grant not found with granter %s and grantee %s", feeGranter, feePayer)
}

granted := false
for _, foundCoin := range foundCoins {
_, err := allowance.Accept(ctx, sdk.NewCoins(foundCoin), feeTx.GetMsgs())
if err == nil {
foundCoins = sdk.NewCoins(foundCoin)
granted = true
err = fd.feegrantKeeper.UseGrantedFees(ctx, feeGranter, feePayer, sdk.NewCoins(foundCoin), feeTx.GetMsgs())
if err != nil {
return "", errorsmod.Wrapf(err, "%s does not allow to pay fees for %s", feeGranter, feePayer)
}
break
}
}

if !granted {
return "", errorsmod.Wrapf(err, "%s does not allow to pay fees for %s", feeGranter, feePayer)
}
}

Expand All @@ -152,11 +168,11 @@ func (fd FeeDecorator) checkDeductFee(ctx sdk.Context, feeTx sdk.FeeTx, taxes sd

// deduct the fees
if !foundCoins.IsZero() {
err := DeductFees(fd.bankKeeper, ctx, deductFeesFromAcc, foundCoins)
foundCoins, err := DeductFees(fd.bankKeeper, ctx, deductFeesFromAcc, foundCoins)
if err != nil {
return "", err
}
if !foundCoins.IsZero() && !simulate {
if !simulate {
err := fd.BurnTaxSplit(ctx, foundCoins)
if err != nil {
return "", err
Expand All @@ -183,17 +199,23 @@ func (fd FeeDecorator) checkDeductFee(ctx sdk.Context, feeTx sdk.FeeTx, taxes sd
}

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

err := bankKeeper.SendCoinsFromAccountToModule(ctx, acc.GetAddress(), authtypes.FeeCollectorName, fees)
if err != nil {
return errorsmod.Wrapf(sdkerrors.ErrInsufficientFunds, err.Error())
for _, fee := range fees {
balance := bankKeeper.GetBalance(ctx, acc.GetAddress(), fee.Denom)
if balance.IsGTE(fee) {
err := bankKeeper.SendCoinsFromAccountToModule(ctx, acc.GetAddress(), authtypes.FeeCollectorName, sdk.NewCoins(fee))
if err != nil {
return nil, errorsmod.Wrapf(err, "failed to send fee to fee collector: %s", fee)
}
return sdk.NewCoins(fee), nil
}
}

return nil
return nil, sdkerrors.ErrInsufficientFunds
}

// checkTxFee implements the default fee logic, where the minimum price per
Expand All @@ -209,7 +231,7 @@ func (fd FeeDecorator) checkTxFee(ctx sdk.Context, tx sdk.Tx, taxes sdk.Coins) (
feeCoins := feeTx.GetFee()
gas := feeTx.GetGas()
msgs := feeTx.GetMsgs()
isOracleTx := tax2gasUtils.IsOracleTx(msgs)
isOracleTx := tax2gasutils.IsOracleTx(msgs)
gasPrices := fd.tax2gasKeeper.GetGasPrices(ctx)

// Ensure that the provided fees meet a minimum threshold for the validator,
Expand All @@ -234,7 +256,7 @@ func (fd FeeDecorator) checkTxFee(ctx sdk.Context, tx sdk.Tx, taxes sdk.Coins) (
priority := int64(math.MaxInt64)

if !isOracleTx {
priority = tax2gasUtils.GetTxPriority(feeCoins, int64(gas))
priority = tax2gasutils.GetTxPriority(feeCoins, int64(gas))
}

return priority, nil
Expand Down
41 changes: 0 additions & 41 deletions x/tax2gas/keeper/expected_keeper.go

This file was deleted.

2 changes: 1 addition & 1 deletion x/tax2gas/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,5 @@ func (k Keeper) GetAuthority() string {
}

func (k Keeper) GetGasPrices(ctx sdk.Context) sdk.DecCoins {
return k.GetParams(ctx).GasPrices
return k.GetParams(ctx).GasPrices.Sort()
}
Loading

0 comments on commit ed0ad82

Please sign in to comment.