Skip to content

Commit

Permalink
feat: add AdvanceEpoch message and tx cli endpoint
Browse files Browse the repository at this point in the history
it's useful to have AdvanceEpoch when testing,
but it should be removed for real-world application.
so only using special build flags can enable this feature.
  • Loading branch information
hallazzang committed Sep 15, 2021
1 parent dd15a09 commit 2b1f6e9
Show file tree
Hide file tree
Showing 7 changed files with 494 additions and 54 deletions.
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,10 @@ endif
ldflags += $(LDFLAGS)
ldflags := $(strip $(ldflags))

testing_ldflags = -X github.com/tendermint/farming/x/farming/keeper.enableAdvanceEpoch=true

BUILD_FLAGS := -tags "$(build_tags)" -ldflags '$(ldflags)'
TESTING_BUILD_FLAGS := -tags "$(build_tags)" -ldflags '$(ldflags) $(testing_ldflags)'

all: tools install lint

Expand All @@ -87,6 +90,9 @@ build-linux: go.sum
install: go.sum
go install $(BUILD_FLAGS) ./cmd/farmingd

install-testing: go.sum
go install $(TESTING_BUILD_FLAGS) ./cmd/farmingd

build-reproducible: go.sum
$(DOCKER) rm latest-build || true
$(DOCKER) run --volume=$(CURDIR):/sources:ro \
Expand Down
17 changes: 16 additions & 1 deletion proto/tendermint/farming/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ service Msg {
// Unstake defines a method for unstaking coins from the farming plan
rpc Unstake(MsgUnstake) returns (MsgUnstakeResponse);

// harvest defines a method for claiming farming rewards
// Harvest defines a method for claiming farming rewards
rpc Harvest(MsgHarvest) returns (MsgHarvestResponse);

// AdvanceEpoch defines a method for advancing epoch by one, just for testing purpose
// and shouldn't be used in real world
rpc AdvanceEpoch(MsgAdvanceEpoch) returns (MsgAdvanceEpochResponse);
}

// MsgCreateFixedAmountPlan defines a SDK message for creating a new fixed
Expand Down Expand Up @@ -156,3 +160,14 @@ message MsgHarvest {

// MsgHarvestResponse defines the Msg/MsgHarvestResponse response type.
message MsgHarvestResponse {}

// MsgAdvanceEpoch defines a message to advance epoch by one.
message MsgAdvanceEpoch {
option (gogoproto.goproto_getters) = false;

// requester defines the bech32-encoded address of the requester
string requester = 1;
}

// MsgAdvanceEpochResponse defines the Msg/AdvanceEpoch response type.
message MsgAdvanceEpochResponse {}
28 changes: 28 additions & 0 deletions x/farming/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/gov/client/cli"
gov "github.com/cosmos/cosmos-sdk/x/gov/types"

"github.com/tendermint/farming/x/farming/keeper"
"github.com/tendermint/farming/x/farming/types"
)

Expand All @@ -38,6 +39,9 @@ func GetTxCmd() *cobra.Command {
NewUnstakeCmd(),
NewHarvestCmd(),
)
if keeper.EnableAdvanceEpoch {
farmingTxCmd.AddCommand(NewAdvanceEpochCmd())
}

return farmingTxCmd
}
Expand Down Expand Up @@ -302,6 +306,30 @@ $ %s tx %s harvest --staking-coin-denoms="poolD35A0CC16EE598F90B044CE296A405BA9C
return cmd
}

func NewAdvanceEpochCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "advance-epoch",
Args: cobra.NoArgs,
Short: "advance epoch by one to simulate reward distribution",
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

requesterAcc := clientCtx.GetFromAddress()

msg := types.NewMsgAdvanceEpoch(requesterAcc)

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

flags.AddTxFlagsToCmd(cmd)

return cmd
}

// GetCmdSubmitPublicPlanProposal implements a command handler for submitting a public farming plan transaction to create, update, and delete plan.
func GetCmdSubmitPublicPlanProposal() *cobra.Command {
cmd := &cobra.Command{
Expand Down
14 changes: 14 additions & 0 deletions x/farming/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper

import (
"fmt"
"strconv"

"github.com/tendermint/tendermint/libs/log"

Expand All @@ -12,6 +13,19 @@ import (
"github.com/tendermint/farming/x/farming/types"
)

var (
enableAdvanceEpoch = "false" // set it to "true" using build flags to enable AdvanceEpoch msg handling.
EnableAdvanceEpoch = false
)

func init() {
var err error
EnableAdvanceEpoch, err = strconv.ParseBool(enableAdvanceEpoch)
if err != nil {
panic(err)
}
}

// Keeper of the farming store
type Keeper struct {
storeKey sdk.StoreKey
Expand Down
17 changes: 17 additions & 0 deletions x/farming/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package keeper

import (
"context"
"fmt"

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

Expand Down Expand Up @@ -101,3 +102,19 @@ func (k msgServer) Harvest(goCtx context.Context, msg *types.MsgHarvest) (*types

return &types.MsgHarvestResponse{}, nil
}

// AdvanceEpoch defines a method for advancing epoch by one, just for testing purpose
// and shouldn't be used in real world.
func (k msgServer) AdvanceEpoch(goCtx context.Context, msg *types.MsgAdvanceEpoch) (*types.MsgAdvanceEpochResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

if EnableAdvanceEpoch {
if err := k.Keeper.AdvanceEpoch(ctx); err != nil {
return nil, err
}
} else {
return nil, fmt.Errorf("AdvanceEpoch is disabled")
}

return &types.MsgAdvanceEpochResponse{}, nil
}
32 changes: 32 additions & 0 deletions x/farming/types/msgs.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var (
_ sdk.Msg = (*MsgStake)(nil)
_ sdk.Msg = (*MsgUnstake)(nil)
_ sdk.Msg = (*MsgHarvest)(nil)
_ sdk.Msg = (*MsgAdvanceEpoch)(nil)
)

// Message types for the farming module
Expand All @@ -23,6 +24,7 @@ const (
TypeMsgStake = "stake"
TypeMsgUnstake = "unstake"
TypeMsgHarvest = "harvest"
TypeMsgAdvanceEpoch = "advance_epoch"
)

// NewMsgCreateFixedAmountPlan creates a new MsgCreateFixedAmountPlan.
Expand Down Expand Up @@ -306,3 +308,33 @@ func (msg MsgHarvest) GetFarmer() sdk.AccAddress {
}
return addr
}

// NewMsgAdvanceEpoch creates a new MsgAdvanceEpoch.
func NewMsgAdvanceEpoch(requesterAcc sdk.AccAddress) *MsgAdvanceEpoch {
return &MsgAdvanceEpoch{
Requester: requesterAcc.String(),
}
}

func (msg MsgAdvanceEpoch) Route() string { return RouterKey }

func (msg MsgAdvanceEpoch) Type() string { return TypeMsgAdvanceEpoch }

func (msg MsgAdvanceEpoch) ValidateBasic() error {
if _, err := sdk.AccAddressFromBech32(msg.Requester); err != nil {
return sdkerrors.Wrapf(sdkerrors.ErrInvalidAddress, "invalid requester address %q: %v", msg.Requester, err)
}
return nil
}

func (msg MsgAdvanceEpoch) GetSignBytes() []byte {
return sdk.MustSortJSON(legacy.Cdc.MustMarshalJSON(&msg))
}

func (msg MsgAdvanceEpoch) GetSigners() []sdk.AccAddress {
addr, err := sdk.AccAddressFromBech32(msg.Requester)
if err != nil {
panic(err)
}
return []sdk.AccAddress{addr}
}
Loading

0 comments on commit 2b1f6e9

Please sign in to comment.