Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
3 changes: 2 additions & 1 deletion app/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {
ante.NewTxTimeoutHeightDecorator(),
ante.NewValidateMemoDecorator(options.AccountKeeper),
ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper),
ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper),
// custom archway fee deduction, which splits fees between gastracker and auths fee collector
gastrackerante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.GasTrackingKeeper),
// SetPubKeyDecorator must be called before all signature verification decorators
ante.NewSetPubKeyDecorator(options.AccountKeeper),
ante.NewValidateSigCountDecorator(options.AccountKeeper),
Expand Down
21 changes: 12 additions & 9 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app

import (
"fmt"
"github.com/archway-network/archway/x/gastracker/mintbankkeeper"
"io"
"net/http"
"os"
Expand Down Expand Up @@ -368,15 +369,6 @@ func NewArchwayApp(
app.bankKeeper,
app.getSubspace(stakingtypes.ModuleName),
)
app.mintKeeper = mintkeeper.NewKeeper(
appCodec,
keys[minttypes.StoreKey],
app.getSubspace(minttypes.ModuleName),
&stakingKeeper,
app.accountKeeper,
app.bankKeeper,
authtypes.FeeCollectorName,
)
app.distrKeeper = distrkeeper.NewKeeper(
appCodec,
keys[distrtypes.StoreKey],
Expand Down Expand Up @@ -505,6 +497,17 @@ func NewArchwayApp(
app.mintKeeper,
)

// note we set up mint keeper after gastracking keeper
app.mintKeeper = mintkeeper.NewKeeper(
appCodec,
keys[minttypes.StoreKey],
app.getSubspace(minttypes.ModuleName),
&stakingKeeper,
app.accountKeeper,
mintbankkeeper.NewKeeper(app.bankKeeper, app.gastrackingKeeper),
authtypes.FeeCollectorName,
)

// Setting gas recorder here to avoid cyclic loop
trackingWasmVm.SetGasRecorder(app.gastrackingKeeper)

Expand Down
108 changes: 108 additions & 0 deletions x/gastracker/ante/fee_deduction.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package ante

import (
"fmt"
"github.com/archway-network/archway/x/gastracker"
"github.com/archway-network/archway/x/gastracker/common"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
"github.com/cosmos/cosmos-sdk/x/auth/types"
)

// 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 {
ak ante.AccountKeeper
bankKeeper types.BankKeeper
feegrantKeeper ante.FeegrantKeeper
gasTrackingKeeper GasTrackingKeeper
}

func NewDeductFeeDecorator(ak ante.AccountKeeper, bk types.BankKeeper, fk ante.FeegrantKeeper, gt GasTrackingKeeper) DeductFeeDecorator {
return DeductFeeDecorator{
ak: ak,
bankKeeper: bk,
feegrantKeeper: fk,
gasTrackingKeeper: gt,
}
}

func (dfd DeductFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
feeTx, ok := tx.(sdk.FeeTx)
if !ok {
return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx")
}

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

fee := feeTx.GetFee()
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 ctx, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "fee grants are not enabled")
} else if !feeGranter.Equals(feePayer) {
err := dfd.feegrantKeeper.UseGrantedFees(ctx, feeGranter, feePayer, fee, tx.GetMsgs())

if err != nil {
return ctx, sdkerrors.Wrapf(err, "%s not allowed to pay fees from %s", feeGranter, feePayer)
}
}

deductFeesFrom = feeGranter
}

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

// deduct the fees
if !feeTx.GetFee().IsZero() {
err = DeductFees(dfd.bankKeeper, dfd.gasTrackingKeeper, ctx, deductFeesFromAcc, feeTx.GetFee())
if err != nil {
return ctx, err
}
}

events := sdk.Events{sdk.NewEvent(sdk.EventTypeTx,
sdk.NewAttribute(sdk.AttributeKeyFee, feeTx.GetFee().String()),
)}
ctx.EventManager().EmitEvents(events)

return next(ctx, tx, simulate)
}

// DeductFees deducts fees from the given account.
// NOTE: this is the only logic being changed
func DeductFees(bankKeeper types.BankKeeper, gt GasTrackingKeeper, ctx sdk.Context, acc types.AccountI, fees sdk.Coins) error {
if !fees.IsValid() {
return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFee, "invalid fee amount: %s", fees)
}

params := gt.GetParams(ctx)

authFees, gasTrackerFees := common.SplitCoins(params.DappTxFeeRebateRatio, fees)

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

err = bankKeeper.SendCoinsFromAccountToModule(ctx, acc.GetAddress(), gastracker.ContractRewardCollector, gasTrackerFees)
if err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, err.Error())
}

return nil
}
File renamed without changes.
20 changes: 20 additions & 0 deletions x/gastracker/common/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package common

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

func SplitCoins(ratio sdk.Dec, fees sdk.Coins) (authCoins, gasTrackerCoins sdk.Coins) {
authCoins = make(sdk.Coins, len(fees))
gasTrackerCoins = make(sdk.Coins, len(fees))

for i, feeCoin := range fees {
gasTrackerCoin := sdk.Coin{
Denom: feeCoin.Denom,
Amount: feeCoin.Amount.ToDec().Mul(ratio).TruncateInt(),
}

gasTrackerCoins[i] = gasTrackerCoin
authCoins[i] = feeCoin.Sub(gasTrackerCoin)
}

return authCoins, gasTrackerCoins
}
66 changes: 66 additions & 0 deletions x/gastracker/mintbankkeeper/keeper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package mintbankkeeper

import (
"github.com/archway-network/archway/x/gastracker"
"github.com/archway-network/archway/x/gastracker/common"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
minttypes "github.com/cosmos/cosmos-sdk/x/mint/types"
)

var (
_ minttypes.BankKeeper = (*Keeper)(nil)
)

type GasTrackingKeeper interface {
GetParams(ctx sdk.Context) gastracker.Params
}

func NewKeeper(bk minttypes.BankKeeper, gtk GasTrackingKeeper) Keeper {
return Keeper{
bk: bk,
gtk: gtk,
}
}

// Keeper mocks the behaviour of the bank keeper required
// by the mint module and splits inflationary rewards
// between the gas tracking module and auth's fee collector
type Keeper struct {
bk minttypes.BankKeeper
gtk GasTrackingKeeper
}

// SendCoinsFromModuleToModule overrides the behaviour of mint's BankKeeper and redirects part of inflationary
// rewards towards the gastracker module.
func (k Keeper) SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error {
// we only care about this if the recipient is fee collector
// (which for instance is always the case)
if recipientModule != authtypes.FeeCollectorName {
return k.bk.SendCoinsFromModuleToModule(ctx, senderModule, recipientModule, amt)
}

ratio := k.gtk.GetParams(ctx).DappInflationRewardsRatio
stakingRewards, dappRewards := common.SplitCoins(ratio, amt)

// send to auth's fee collector
err := k.bk.SendCoinsFromModuleToModule(ctx, senderModule, recipientModule, stakingRewards)
if err != nil {
return err
}
// send to gastracker
err = k.bk.SendCoinsFromModuleToModule(ctx, senderModule, gastracker.ContractRewardCollector, dappRewards)
if err != nil {
return err
}

return nil
}

func (k Keeper) SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error {
return k.bk.SendCoinsFromModuleToAccount(ctx, senderModule, recipientAddr, amt)
}

func (k Keeper) MintCoins(ctx sdk.Context, name string, amt sdk.Coins) error {
return k.bk.MintCoins(ctx, name, amt)
}
12 changes: 0 additions & 12 deletions x/gastracker/module/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

"github.com/cosmos/cosmos-sdk/telemetry"
sdk "github.com/cosmos/cosmos-sdk/types"
authTypes "github.com/cosmos/cosmos-sdk/x/auth/types"
mintTypes "github.com/cosmos/cosmos-sdk/x/mint/types"
abci "github.com/tendermint/tendermint/abci/types"

Expand All @@ -15,7 +14,6 @@ import (

type RewardTransferKeeper interface {
SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error
SendCoinsFromModuleToModule(ctx sdk.Context, senderModule, recipientModule string, amt sdk.Coins) error
}

type MintParamsKeeper interface {
Expand Down Expand Up @@ -48,16 +46,6 @@ func BeginBlock(context sdk.Context, _ abci.RequestBeginBlock, gasTrackingKeeper
return
}

totalFeeToBeCollected := make(sdk.Coins, len(totalContractRewardsPerBlock))
for i := range totalFeeToBeCollected {
totalFeeToBeCollected[i] = sdk.NewCoin(totalContractRewardsPerBlock[i].Denom, totalContractRewardsPerBlock[i].Amount.Ceil().RoundInt())
}

err := rewardTransferKeeper.SendCoinsFromModuleToModule(context, authTypes.FeeCollectorName, gstTypes.ContractRewardCollector, totalFeeToBeCollected)
if err != nil {
panic(err)
}

distributeRewards(context, rewardAddresses, rewardsByAddress, gasTrackingKeeper, rewardTransferKeeper)
}

Expand Down
9 changes: 0 additions & 9 deletions x/gastracker/module/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
gstTypes "github.com/archway-network/archway/x/gastracker"
"github.com/archway-network/archway/x/gastracker/testutil"
sdk "github.com/cosmos/cosmos-sdk/types"
authTypes "github.com/cosmos/cosmos-sdk/x/auth/types"
mintTypes "github.com/cosmos/cosmos-sdk/x/mint/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/abci/types"
Expand Down Expand Up @@ -268,7 +267,6 @@ func TestRewardCalculation(t *testing.T) {
sdk.NewDecCoinFromDec("test1", sdk.MustNewDecFromStr("0.683333333333333333")),
},
logs: []*RewardTransferKeeperCallLogs{
createLogModule(authTypes.FeeCollectorName, gstTypes.ContractRewardCollector, sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(3)), sdk.NewCoin("test1", sdk.NewInt(1)))),
createLogAddr(gstTypes.ContractRewardCollector, spareAddress[5].String(), sdk.NewCoins()),
createLogAddr(gstTypes.ContractRewardCollector, spareAddress[6].String(), sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(2)))),
},
Expand Down Expand Up @@ -394,9 +392,6 @@ func TestRewardCalculation(t *testing.T) {
}
}

//func TestRewardCalculation(t *testing.T) {
//}

func TestContractRewardsWithoutContractPremium(t *testing.T) {
config := sdk.GetConfig()
config.SetBech32PrefixForAccount("archway", "archway")
Expand All @@ -422,7 +417,6 @@ func TestContractRewardsWithoutContractPremium(t *testing.T) {
sdk.NewDecCoinFromDec("test1", sdk.MustNewDecFromStr("0.666666666666666666")),
},
logs: []*RewardTransferKeeperCallLogs{
createLogModule(authTypes.FeeCollectorName, gstTypes.ContractRewardCollector, sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(3)), sdk.NewCoin("test1", sdk.NewInt(1)))),
createLogAddr(gstTypes.ContractRewardCollector, spareAddress[5].String(), sdk.NewCoins()),
createLogAddr(gstTypes.ContractRewardCollector, spareAddress[6].String(), sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(2)))),
},
Expand Down Expand Up @@ -571,7 +565,6 @@ func TestContractRewardsWithoutDappInflation(t *testing.T) {
sdk.NewDecCoinFromDec("test1", sdk.MustNewDecFromStr("0.683333333333333333")),
},
logs: []*RewardTransferKeeperCallLogs{
createLogModule(authTypes.FeeCollectorName, gstTypes.ContractRewardCollector, sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(3)), sdk.NewCoin("test1", sdk.NewInt(1)))),
createLogAddr(gstTypes.ContractRewardCollector, spareAddress[5].String(), sdk.NewCoins()),
createLogAddr(gstTypes.ContractRewardCollector, spareAddress[6].String(), sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(2)))),
},
Expand Down Expand Up @@ -719,7 +712,6 @@ func TestContractRewardsWithoutGasRebate(t *testing.T) {
sdk.NewDecCoinFromDec("test", sdk.MustNewDecFromStr("0.005355")),
},
logs: []*RewardTransferKeeperCallLogs{
createLogModule(authTypes.FeeCollectorName, gstTypes.ContractRewardCollector, sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(1)))),
createLogAddr(gstTypes.ContractRewardCollector, spareAddress[5].String(), sdk.NewCoins()),
createLogAddr(gstTypes.ContractRewardCollector, spareAddress[6].String(), sdk.NewCoins()),
},
Expand Down Expand Up @@ -1137,7 +1129,6 @@ func TestContractRewardsWithoutGasRebateToUser(t *testing.T) {
sdk.NewDecCoinFromDec("test1", sdk.MustNewDecFromStr("0.683333333333333333")),
},
logs: []*RewardTransferKeeperCallLogs{
createLogModule(authTypes.FeeCollectorName, gstTypes.ContractRewardCollector, sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(3)), sdk.NewCoin("test1", sdk.NewInt(1)))),
createLogAddr(gstTypes.ContractRewardCollector, spareAddress[5].String(), sdk.NewCoins()),
createLogAddr(gstTypes.ContractRewardCollector, spareAddress[6].String(), sdk.NewCoins(sdk.NewCoin("test", sdk.NewInt(2)))),
},
Expand Down