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

[Feature] minimum commission rate upgrade #47

Closed
wants to merge 12 commits into from
8 changes: 7 additions & 1 deletion app/ante/ante.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ante

import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/auth/ante"
Expand All @@ -9,16 +10,20 @@ import (

wasmkeeper "github.com/CosmWasm/wasmd/x/wasm/keeper"
wasmTypes "github.com/CosmWasm/wasmd/x/wasm/types"
antekeeper "github.com/terra-money/core/v2/app/ante/keeper"
)

// HandlerOptions extends the SDK's AnteHandler options by requiring the IBC
// channel keeper.
type HandlerOptions struct {
ante.HandlerOptions

IBCkeeper *ibckeeper.Keeper
IBCkeeper *ibckeeper.Keeper
AnteKeeper *antekeeper.Keeper

TxCounterStoreKey sdk.StoreKey
WasmConfig wasmTypes.WasmConfig
Cdc codec.BinaryCodec
}

// NewAnteHandler returns an AnteHandler that checks and increments sequence
Expand All @@ -44,6 +49,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) {

anteDecorators := []sdk.AnteDecorator{
ante.NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first
NewMinCommissionDecorator(options.Cdc, options.AnteKeeper),
wasmkeeper.NewLimitSimulationGasDecorator(options.WasmConfig.SimulationGasLimit),
wasmkeeper.NewCountTXDecorator(options.TxCounterStoreKey),
ante.NewRejectExtensionOptionsDecorator(),
Expand Down
3 changes: 3 additions & 0 deletions app/ante/ante_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"

terraapp "github.com/terra-money/core/v2/app"
antetypes "github.com/terra-money/core/v2/app/ante/types"
"github.com/terra-money/core/v2/app/wasmconfig"
)

Expand All @@ -47,6 +48,8 @@ func createTestApp(isCheckTx bool, tempDir string) (*terraapp.TerraApp, sdk.Cont
)
ctx := app.BaseApp.NewContext(isCheckTx, tmproto.Header{})
app.AccountKeeper.SetParams(ctx, authtypes.DefaultParams())
app.AnteKeeper.SetParams(ctx, antetypes.DefaultParams())
app.AnteKeeper.SetMinimumCommission(ctx, antetypes.DefaultMinimumCommission)

return app, ctx
}
Expand Down
93 changes: 93 additions & 0 deletions app/ante/client/cli/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package cli

import (
"strings"

"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/flags"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/terra-money/core/v2/app/ante/types"
)

// GetQueryCmd returns the transaction commands for this module
func GetQueryCmd() *cobra.Command {
cmd := &cobra.Command{
Use: types.ModuleName,
Short: "Querying commands for the ante module",
DisableFlagParsing: true,
SuggestionsMinimumDistance: 2,
RunE: client.ValidateCmd,
}

cmd.AddCommand(
QueryParamsCmd(),
QueryMinimumCommissionCmd(),
)

return cmd
}

// QueryParamsCmd returns the command handler for ante parameter querying.
func QueryParamsCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "params",
Short: "Query the current ante parameters",
Args: cobra.NoArgs,
Long: strings.TrimSpace(`Query the current ante parameters:

$ <appd> query ante params
`),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}

queryClient := types.NewQueryClient(clientCtx)
res, err := queryClient.Params(cmd.Context(), &types.QueryParamsRequest{})
if err != nil {
return err
}

return clientCtx.PrintProto(&res.Params)
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}

// QueryMinimumCommissionCmd returns the command handler for minimum commission querying.
func QueryMinimumCommissionCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "minimum-commission",
Short: "Query the current minimum commission",
Args: cobra.NoArgs,
Long: strings.TrimSpace(`Query the current minimum commission:

$ <appd> query ante minimum-commission
`),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientQueryContext(cmd)
if err != nil {
return err
}

queryClient := types.NewQueryClient(clientCtx)
res, err := queryClient.MinimumCommission(cmd.Context(), &types.QueryMinimumCommissionRequest{})
if err != nil {
return err
}

return clientCtx.PrintProto(&sdk.DecProto{Dec: res.MinimumCommission})
},
}

flags.AddQueryFlagsToCmd(cmd)

return cmd
}
77 changes: 77 additions & 0 deletions app/ante/client/cli/tx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package cli

import (
"github.com/spf13/cobra"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov/client/cli"
gov "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/terra-money/core/v2/app/ante/types"
)

// NewCmdSubmitMinimumCommissionUpdateProposal implements a command handler for submitting a minimum commission proposal transaction.
func NewCmdSubmitMinimumCommissionUpdateProposal() *cobra.Command {
cmd := &cobra.Command{
Use: "minimum-commission-update [minimum-commission] [flags]",
Args: cobra.ExactArgs(1),
Short: "Submit a minimum commission update proposal",
Long: "Submit a minimum commission update along with an initial deposit.",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
minimumCommissionStr := args[0]
minimumCommission, err := sdk.NewDecFromStr(minimumCommissionStr)
if err != nil {
return err
}

content, err := parseArgsToContent(cmd, minimumCommission)
if err != nil {
return err
}

from := clientCtx.GetFromAddress()

depositStr, err := cmd.Flags().GetString(cli.FlagDeposit)
if err != nil {
return err
}
deposit, err := sdk.ParseCoinsNormalized(depositStr)
if err != nil {
return err
}

msg, err := gov.NewMsgSubmitProposal(content, deposit, from)
if err != nil {
return err
}

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}

cmd.Flags().String(cli.FlagTitle, "", "title of proposal")
cmd.Flags().String(cli.FlagDescription, "", "description of proposal")
cmd.Flags().String(cli.FlagDeposit, "", "deposit of proposal")

return cmd
}

func parseArgsToContent(cmd *cobra.Command, minimumCommission sdk.Dec) (gov.Content, error) {
title, err := cmd.Flags().GetString(cli.FlagTitle)
if err != nil {
return nil, err
}

description, err := cmd.Flags().GetString(cli.FlagDescription)
if err != nil {
return nil, err
}

content := types.NewMinimumCommissionUpdateProposal(title, description, minimumCommission)
return content, nil
}
25 changes: 25 additions & 0 deletions app/ante/client/proposal_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package client

import (
"net/http"

"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/types/rest"
govclient "github.com/cosmos/cosmos-sdk/x/gov/client"
govrest "github.com/cosmos/cosmos-sdk/x/gov/client/rest"

"github.com/terra-money/core/v2/app/ante/client/cli"
)

// ProposalHandler is the minimum commission update proposal handler.
var ProposalHandler = govclient.NewProposalHandler(cli.NewCmdSubmitMinimumCommissionUpdateProposal, emptyHandler)

func emptyHandler(clientCtx client.Context) govrest.ProposalRESTHandler {
return govrest.ProposalRESTHandler{
SubRoute: "ante",
Handler: func(w http.ResponseWriter, r *http.Request) {
rest.WriteErrorResponse(w, http.StatusNotFound, "end point not implemented")
return
},
}
}
31 changes: 31 additions & 0 deletions app/ante/keeper/grpc_querier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package keeper

import (
"context"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/terra-money/core/v2/app/ante/types"
)

// Querier is used as Keeper will have duplicate methods if used directly, and gRPC names take precedence over keeper
type Querier struct {
Keeper
}

var _ types.QueryServer = Querier{}

// Params queries the ante parameters
func (k Querier) Params(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
params := k.GetParams(ctx)

return &types.QueryParamsResponse{Params: params}, nil
}

// MinimumCommission queries the minimum commission
func (k Querier) MinimumCommission(c context.Context, _ *types.QueryMinimumCommissionRequest) (*types.QueryMinimumCommissionResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
minimumCommission := k.GetMinimumCommission(ctx)

return &types.QueryMinimumCommissionResponse{MinimumCommission: minimumCommission}, nil
}
76 changes: 76 additions & 0 deletions app/ante/keeper/grpc_querier_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package keeper_test

import (
gocontext "context"
"fmt"

"github.com/terra-money/core/v2/app/ante/types"
)

func (suite *KeeperTestSuite) TestGRPCQueryParams() {
suite.SetupTest(true) // setup
queryClient := suite.queryClient

var req *types.QueryParamsRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"valid request",
func() {
req = &types.QueryParamsRequest{}
},
true,
},
}

for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.Params(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.True(res.Params.Equal(types.DefaultParams()))
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}

func (suite *KeeperTestSuite) TestGRPCQueryMinimumCommission() {
suite.SetupTest(true) // setup
queryClient := suite.queryClient

var req *types.QueryMinimumCommissionRequest
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{
"valid request",
func() {
req = &types.QueryMinimumCommissionRequest{}
},
true,
},
}

for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
tc.malleate()
res, err := queryClient.MinimumCommission(gocontext.Background(), req)
if tc.expPass {
suite.NoError(err)
suite.True(res.MinimumCommission.Equal(types.DefaultMinimumCommission))
} else {
suite.Error(err)
suite.Nil(res)
}
})
}
}
Loading