From f9941438caa3d2a428b1b442fff6ce44bab39caf Mon Sep 17 00:00:00 2001 From: JayB Date: Fri, 8 Oct 2021 14:11:42 +0900 Subject: [PATCH] feat: add examples of multiple coins for command-line interfaces (#156) * docs: update stake description * refactor: add more usage examples and update description * chore: add more test cases, refactor codes, and rename suite.go to suite_test.go * docs: update the link * feat: increase code coverage * test: code coverage * test: change the file name since coverage counts lines * revert: test lines * feat: apply feedbacks * chore: increase code coverage and remove unused sentinel error --- x/farming/client/cli/tx.go | 28 ++- x/farming/client/testutil/cli_helpers.go | 29 +++ x/farming/client/testutil/suite.go | 249 +++++++++++++---------- x/farming/keeper/reward.go | 3 +- x/farming/keeper/reward_test.go | 5 +- x/farming/types/errors.go | 9 +- 6 files changed, 198 insertions(+), 125 deletions(-) diff --git a/x/farming/client/cli/tx.go b/x/farming/client/cli/tx.go index 31466716..069763e4 100644 --- a/x/farming/client/cli/tx.go +++ b/x/farming/client/cli/tx.go @@ -193,12 +193,14 @@ func NewStakeCmd() *cobra.Command { Long: strings.TrimSpace( fmt.Sprintf(`Stake coins. -To get farming rewards, it is recommended to check which plans are available on a network. +To get farming rewards, you must stake coins that are defined in available plans on a network. Example: $ %s tx %s stake 1000poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4 --from mykey +$ %s tx %s stake 500poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4,500pool93E069B333B5ECEBFE24C6E1437E814003248E0DD7FF8B9F82119F4587449BA5 --from mykey `, version.AppName, types.ModuleName, + version.AppName, types.ModuleName, ), ), RunE: func(cmd *cobra.Command, args []string) error { @@ -233,12 +235,14 @@ func NewUnstakeCmd() *cobra.Command { Long: strings.TrimSpace( fmt.Sprintf(`Unstake coins. -Note that this action doesn't require any period to unstake your coins. +Note that unstaking doesn't require any period and your accumulated rewards are automatically withdrawn to your wallet. Example: $ %s tx %s unstake 500poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4 --from mykey +$ %s tx %s unstake 500poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4,500pool93E069B333B5ECEBFE24C6E1437E814003248E0DD7FF8B9F82119F4587449BA5 --from mykey `, version.AppName, types.ModuleName, + version.AppName, types.ModuleName, ), ), RunE: func(cmd *cobra.Command, args []string) error { @@ -271,14 +275,16 @@ func NewHarvestCmd() *cobra.Command { Args: cobra.MaximumNArgs(1), Short: "Harvest farming rewards", Long: strings.TrimSpace( - fmt.Sprintf(`Harvest farming that the staking coin denoms belong to plans. + fmt.Sprintf(`Harvest farming rewards from the staking coin denoms that are defined in the availble plans. Example: -$ %s tx %s harvest poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4,uatom --from mykey +$ %s tx %s harvest poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4 --from mykey +$ %s tx %s harvest poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4,pool93E069B333B5ECEBFE24C6E1437E814003248E0DD7FF8B9F82119F4587449BA5 --from mykey $ %s tx %s harvest --all --from mykey `, version.AppName, types.ModuleName, version.AppName, types.ModuleName, + version.AppName, types.ModuleName, ), ), RunE: func(cmd *cobra.Command, args []string) error { @@ -332,7 +338,17 @@ func NewAdvanceEpochCmd() *cobra.Command { cmd := &cobra.Command{ Use: "advance-epoch", Args: cobra.NoArgs, - Short: "advance epoch by one to simulate reward distribution", + Short: "Advance epoch by 1 to simulate reward distribution", + Long: strings.TrimSpace( + fmt.Sprintf(`Advance epoch by 1 to simulate reward distribution. +This message is available for testing purpose and it can only be enabled when you build the binary with "make install-testing" command. + +Example: +$ %s tx %s advance-epoch --from mykey +`, + version.AppName, types.ModuleName, + ), + ), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientTxContext(cmd) if err != nil { @@ -361,7 +377,7 @@ func GetCmdSubmitPublicPlanProposal() *cobra.Command { Long: strings.TrimSpace( fmt.Sprintf(`Submit a a public farming plan along with an initial deposit. You can submit this governance proposal to add, update, and delete farming plan. The proposal details must be supplied via a JSON file. A JSON file to add plan request proposal is -provided below. For more examples, please refer to https://github.com/tendermint/farming/blob/master/docs/How-To/farming_plans.md +provided below. For more examples, please refer to https://github.com/tendermint/farming/blob/master/docs/Tutorials/demo/plans.md Example: $ %s tx gov submit-proposal public-farming-plan --from= --deposit= diff --git a/x/farming/client/testutil/cli_helpers.go b/x/farming/client/testutil/cli_helpers.go index 9a371fb8..300a022c 100644 --- a/x/farming/client/testutil/cli_helpers.go +++ b/x/farming/client/testutil/cli_helpers.go @@ -16,6 +16,7 @@ import ( clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/testutil/network" sdk "github.com/cosmos/cosmos-sdk/types" + bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/cli" farmingapp "github.com/tendermint/farming/app" farmingcli "github.com/tendermint/farming/x/farming/client/cli" @@ -78,3 +79,31 @@ func MsgStakeExec(clientCtx client.Context, from string, stakingCoins string, return clitestutil.ExecTestCLICmd(clientCtx, farmingcli.NewStakeCmd(), args) } + +// MsgAdvanceEpochExec creates a transaction to advance epoch by 1. +func MsgAdvanceEpochExec(clientCtx client.Context, from string, + extraAtgs ...string) (testutil.BufferWriter, error) { + + args := append([]string{ + fmt.Sprintf("--%s=%s", flags.FlagFrom, from), + }, commonArgs...) + + args = append(args, commonArgs...) + + return clitestutil.ExecTestCLICmd(clientCtx, farmingcli.NewAdvanceEpochCmd(), args) +} + +// MsgSendExec creates a transaction to transfer coins. +func MsgSendExec(clientCtx client.Context, from string, to string, amount string, + extraAtgs ...string) (testutil.BufferWriter, error) { + + args := append([]string{ + from, + to, + amount, + }, commonArgs...) + + args = append(args, commonArgs...) + + return clitestutil.ExecTestCLICmd(clientCtx, bankcli.NewSendTxCmd(), args) +} diff --git a/x/farming/client/testutil/suite.go b/x/farming/client/testutil/suite.go index 8882c2a5..4c266ce6 100644 --- a/x/farming/client/testutil/suite.go +++ b/x/farming/client/testutil/suite.go @@ -2,9 +2,7 @@ package testutil import ( "fmt" - "os" "strconv" - "time" "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/suite" @@ -16,7 +14,6 @@ import ( clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/testutil/network" sdk "github.com/cosmos/cosmos-sdk/types" - bankcli "github.com/cosmos/cosmos-sdk/x/bank/client/cli" "github.com/tendermint/farming/x/farming/client/cli" farmingcli "github.com/tendermint/farming/x/farming/client/cli" @@ -39,6 +36,8 @@ type IntegrationTestSuite struct { func (s *IntegrationTestSuite) SetupTest() { s.T().Log("setting up integration test suite") + farmingkeeper.EnableAdvanceEpoch = true + db := tmdb.NewMemDB() cfg := NewConfig(db) cfg.NumValidators = 1 @@ -406,24 +405,35 @@ func (s *IntegrationTestSuite) TestNewStakeCmd() { expectedCode uint32 }{ { - "valid transaction", + "valid transaction case #1", []string{ - sdk.NewCoin("stake", sdk.NewInt(100000)).String(), + sdk.NewInt64Coin("stake", 100000).String(), fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 10)).String()), + }, + false, &sdk.TxResponse{}, 0, + }, + { + "valid transaction case #2", + []string{ + sdk.NewCoins(sdk.NewInt64Coin("stake", 100000), sdk.NewInt64Coin("node0token", 100000)).String(), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 10)).String()), }, false, &sdk.TxResponse{}, 0, }, { "invalid staking coin case #1", []string{ - sdk.NewCoin("stake", sdk.NewInt(0)).String(), + sdk.NewInt64Coin("stake", 0).String(), fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 10)).String()), }, true, &sdk.TxResponse{}, 0, }, @@ -457,7 +467,10 @@ func (s *IntegrationTestSuite) TestNewUnstakeCmd() { _, err := MsgStakeExec( val.ClientCtx, val.Address.String(), - sdk.NewCoin("stake", sdk.NewInt(10_000_000)).String(), + sdk.NewCoins( + sdk.NewInt64Coin("stake", 10_000_000), + sdk.NewInt64Coin("node0token", 10_000_000), + ).String(), ) s.Require().NoError(err) @@ -469,24 +482,35 @@ func (s *IntegrationTestSuite) TestNewUnstakeCmd() { expectedCode uint32 }{ { - "valid transaction", + "valid transaction case #1", []string{ - sdk.NewCoin("stake", sdk.NewInt(100000)).String(), + sdk.NewInt64Coin("stake", 100000).String(), fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 10)).String()), + }, + false, &sdk.TxResponse{}, 0, + }, + { + "valid transaction case #2", + []string{ + sdk.NewCoins(sdk.NewInt64Coin("stake", 100000), sdk.NewInt64Coin("node0token", 100000)).String(), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 10)).String()), }, false, &sdk.TxResponse{}, 0, }, { "invalid unstaking coin case #1", []string{ - sdk.NewCoin("stake", sdk.NewInt(0)).String(), + sdk.NewInt64Coin("stake", 0).String(), fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 10)).String()), }, true, &sdk.TxResponse{}, 18, }, @@ -508,8 +532,6 @@ func (s *IntegrationTestSuite) TestNewUnstakeCmd() { s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String()) txResp := tc.respType.(*sdk.TxResponse) - fmt.Println(txResp) - fmt.Println(out.String()) s.Require().Equal(tc.expectedCode, txResp.Code, out.String()) } }) @@ -519,7 +541,6 @@ func (s *IntegrationTestSuite) TestNewUnstakeCmd() { func (s *IntegrationTestSuite) TestNewHarvestCmd() { val := s.network.Validators[0] - // create fixed amount plan req := cli.PrivateFixedPlanRequest{ Name: "test", StakingCoinWeights: sdk.NewDecCoins(sdk.NewDecCoin("stake", sdk.NewInt(1))), @@ -528,6 +549,7 @@ func (s *IntegrationTestSuite) TestNewHarvestCmd() { EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("node0token", 100_000_000)), } + // create a fixed amount plan _, err := MsgCreateFixedAmountPlanExec( val.ClientCtx, val.Address.String(), @@ -535,17 +557,30 @@ func (s *IntegrationTestSuite) TestNewHarvestCmd() { ) s.Require().NoError(err) - // stake coins + // stake coin _, err = MsgStakeExec( val.ClientCtx, val.Address.String(), - sdk.NewCoin("stake", sdk.NewInt(10_000_000)).String(), + sdk.NewCoins( + sdk.NewInt64Coin("stake", 10_000_000), + sdk.NewInt64Coin("node0token", 10_000_000), + ).String(), + ) + s.Require().NoError(err) + + // advance epoch by 1 + _, err = MsgAdvanceEpochExec( + val.ClientCtx, + val.Address.String(), ) s.Require().NoError(err) - // TODO: right now, there is no command-line interface that triggers keeeper - // to increase epoch days by 2 for reward distribution. - // handle invalid cases for now + // advance epoch by 1 + _, err = MsgAdvanceEpochExec( + val.ClientCtx, + val.Address.String(), + ) + s.Require().NoError(err) testCases := []struct { name string @@ -555,24 +590,46 @@ func (s *IntegrationTestSuite) TestNewHarvestCmd() { expectedCode uint32 }{ { - "invalid transaction for no reward for staking coin denom stake", + "valid transaction case #1", []string{ "stake", fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 10)).String()), + }, + false, &sdk.TxResponse{}, 0, + }, + { + "valid transaction case #2", + []string{ + "stake,node0token", + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 10)).String()), + }, + false, &sdk.TxResponse{}, 0, + }, + { + "valid transaction case #3", + []string{ + fmt.Sprintf("--%s", cli.FlagAll), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 10)).String()), }, - false, &sdk.TxResponse{}, 1, + false, &sdk.TxResponse{}, 0, }, { "invalid staking coin denoms case #1", []string{ - "!", + "invaliddenom!", fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastBlock), - fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, sdk.NewInt(10))).String()), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewInt64Coin(s.cfg.BondDenom, 10)).String()), }, true, &sdk.TxResponse{}, 18, }, @@ -610,6 +667,8 @@ type QueryCmdTestSuite struct { func (s *QueryCmdTestSuite) SetupSuite() { s.T().Log("setting up integration test suite") + farmingkeeper.EnableAdvanceEpoch = true + db := tmdb.NewMemDB() cfg := NewConfig(db) cfg.NumValidators = 1 @@ -629,105 +688,45 @@ func (s *QueryCmdTestSuite) SetupSuite() { _, err = s.network.WaitForHeight(1) s.Require().NoError(err) - s.createFixedAmountPlan( - "test", - sdk.NewDecCoins(sdk.NewInt64DecCoin(sdk.DefaultBondDenom, 1)), - types.ParseTime("0001-01-01T00:00:00Z"), - types.ParseTime("9999-01-01T00:00:00Z"), - sdk.NewCoins(sdk.NewInt64Coin("node0token", 100_000_000)), - ) - s.fundFarmingPool(1, sdk.NewCoins(sdk.NewInt64Coin("node0token", 1_000_000_000))) - s.stake(sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 1000000))) - s.advanceEpoch() - s.advanceEpoch() -} - -func (s *QueryCmdTestSuite) TearDownSuite() { - s.T().Log("tearing down integration test suite") - s.network.Cleanup() -} - -func (s *QueryCmdTestSuite) createFixedAmountPlan(name string, stakingCoinWeights sdk.DecCoins, startTime, endTime time.Time, epochAmount sdk.Coins) { val := s.network.Validators[0] - clientCtx := val.ClientCtx req := cli.PrivateFixedPlanRequest{ - Name: name, - StakingCoinWeights: stakingCoinWeights, - StartTime: startTime, - EndTime: endTime, - EpochAmount: epochAmount, + Name: "test", + StakingCoinWeights: sdk.NewDecCoins(sdk.NewInt64DecCoin(sdk.DefaultBondDenom, 1)), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), + EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("node0token", 100_000_000)), } - file := testutil.WriteToNewTempFile(s.T(), req.String()) - defer os.Remove(file.Name()) - - args := append([]string{ - file.Name(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - }, commonArgs...) - - cmd := farmingcli.NewCreateFixedAmountPlanCmd() - _, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + // create a fixed amount plan + _, err = MsgCreateFixedAmountPlanExec( + val.ClientCtx, + val.Address.String(), + testutil.WriteToNewTempFile(s.T(), req.String()).Name(), + ) s.Require().NoError(err) -} - -func (s *QueryCmdTestSuite) fundFarmingPool(poolId uint64, amount sdk.Coins) { - val := s.network.Validators[0] - clientCtx := val.ClientCtx - types.RegisterInterfaces(clientCtx.InterfaceRegistry) - cmd := farmingcli.GetCmdQueryPlan() - args := []string{ - strconv.FormatUint(poolId, 10), - fmt.Sprintf("--%s=json", tmcli.OutputFlag), - } - out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args) - s.Require().NoError(err) - var resp types.QueryPlanResponse - clientCtx.Codec.MustUnmarshalJSON(out.Bytes(), &resp) - plan, err := types.UnpackPlan(resp.Plan) - s.Require().NoError(err) + // query the farming pool address that is assigned to the pool and + // trasnfer some amount of coins to the address + s.fundFarmingPool(1, sdk.NewCoins(sdk.NewInt64Coin("node0token", 1_000_000_000))) - cmd = bankcli.NewSendTxCmd() - args = append([]string{ + _, err = MsgStakeExec( + val.ClientCtx, val.Address.String(), - plan.GetFarmingPoolAddress().String(), - amount.String(), - }, commonArgs...) - _, err = clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 1000000)).String(), + ) s.Require().NoError(err) -} -func (s *QueryCmdTestSuite) stake(amount sdk.Coins) { - val := s.network.Validators[0] - clientCtx := val.ClientCtx - - args := append([]string{ - amount.String(), - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - }, commonArgs...) - - cmd := farmingcli.NewStakeCmd() + _, err = MsgAdvanceEpochExec(val.ClientCtx, val.Address.String()) + s.Require().NoError(err) - _, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + _, err = MsgAdvanceEpochExec(val.ClientCtx, val.Address.String()) s.Require().NoError(err) } -func (s *QueryCmdTestSuite) advanceEpoch() { - farmingkeeper.EnableAdvanceEpoch = true - - val := s.network.Validators[0] - clientCtx := val.ClientCtx - - args := append([]string{ - fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()), - }, commonArgs...) - - cmd := farmingcli.NewAdvanceEpochCmd() - - _, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args) - s.Require().NoError(err) +func (s *QueryCmdTestSuite) TearDownSuite() { + s.T().Log("tearing down integration test suite") + s.network.Cleanup() } func (s *QueryCmdTestSuite) TestCmdQueryParams() { @@ -1087,6 +1086,34 @@ func (s *QueryCmdTestSuite) TestCmdQueryCurrentEpochDays() { } } +func (s *QueryCmdTestSuite) fundFarmingPool(poolId uint64, amount sdk.Coins) { + val := s.network.Validators[0] + clientCtx := val.ClientCtx + types.RegisterInterfaces(clientCtx.InterfaceRegistry) + + cmd := farmingcli.GetCmdQueryPlan() + args := []string{ + strconv.FormatUint(poolId, 10), + fmt.Sprintf("--%s=json", tmcli.OutputFlag), + } + + out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, args) + s.Require().NoError(err) + + var resp types.QueryPlanResponse + clientCtx.Codec.MustUnmarshalJSON(out.Bytes(), &resp) + plan, err := types.UnpackPlan(resp.Plan) + s.Require().NoError(err) + + _, err = MsgSendExec( + val.ClientCtx, + val.Address.String(), + plan.GetFarmingPoolAddress().String(), + amount.String(), + ) + s.Require().NoError(err) +} + func intEq(exp, got sdk.Int) (bool, string, string, string) { return exp.Equal(got), "expected:\t%v\ngot:\t\t%v", exp.String(), got.String() } diff --git a/x/farming/keeper/reward.go b/x/farming/keeper/reward.go index d831d066..ea0bc077 100644 --- a/x/farming/keeper/reward.go +++ b/x/farming/keeper/reward.go @@ -1,7 +1,6 @@ package keeper import ( - "fmt" "strconv" sdk "github.com/cosmos/cosmos-sdk/types" @@ -164,7 +163,7 @@ func (k Keeper) AllRewards(ctx sdk.Context, farmerAcc sdk.AccAddress) sdk.Coins func (k Keeper) WithdrawRewards(ctx sdk.Context, farmerAcc sdk.AccAddress, stakingCoinDenom string) (sdk.Coins, error) { staking, found := k.GetStaking(ctx, stakingCoinDenom, farmerAcc) if !found { - return nil, fmt.Errorf("empty starting info") // TODO: use correct error + return nil, types.ErrStakingNotExists } currentEpoch := k.GetCurrentEpoch(ctx, stakingCoinDenom) diff --git a/x/farming/keeper/reward_test.go b/x/farming/keeper/reward_test.go index 3209037e..e54cadc8 100644 --- a/x/farming/keeper/reward_test.go +++ b/x/farming/keeper/reward_test.go @@ -288,12 +288,15 @@ func (suite *KeeperTestSuite) TestHarvest() { suite.keeper.SetPlan(suite.ctx, plan) } + err := suite.keeper.Harvest(suite.ctx, suite.addrs[0], []string{denom1}) + suite.Require().EqualError(types.ErrStakingNotExists, err.Error()) + suite.Stake(suite.addrs[0], sdk.NewCoins(sdk.NewInt64Coin(denom1, 1_000_000))) suite.keeper.ProcessQueuedCoins(suite.ctx) balancesBefore := suite.app.BankKeeper.GetAllBalances(suite.ctx, suite.addrs[0]) suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-08-05T00:00:00Z")) - err := suite.keeper.AllocateRewards(suite.ctx) + err = suite.keeper.AllocateRewards(suite.ctx) suite.Require().NoError(err) rewards := suite.keeper.AllRewards(suite.ctx, suite.addrs[0]) diff --git a/x/farming/types/errors.go b/x/farming/types/errors.go index 0fcffc3e..abb19063 100644 --- a/x/farming/types/errors.go +++ b/x/farming/types/errors.go @@ -13,9 +13,8 @@ var ( ErrRewardNotExists = sdkerrors.Register(ModuleName, 6, "reward not exists") ErrFeeCollectionFailure = sdkerrors.Register(ModuleName, 7, "fee collection failure") ErrInvalidPlanNameLength = sdkerrors.Register(ModuleName, 8, "invalid plan name length") - ErrDuplicatePlanName = sdkerrors.Register(ModuleName, 9, "duplicate plan name") - ErrInvalidPlanName = sdkerrors.Register(ModuleName, 10, "invalid plan name") - ErrConflictPrivatePlanFarmingPool = sdkerrors.Register(ModuleName, 11, "the address is already in use, please use a different plan name") - ErrInvalidStakingReservedAmount = sdkerrors.Register(ModuleName, 12, "staking reserved amount invariant broken") - ErrInvalidRemainingRewardsAmount = sdkerrors.Register(ModuleName, 13, "remaining rewards amount invariant broken") + ErrInvalidPlanName = sdkerrors.Register(ModuleName, 9, "invalid plan name") + ErrConflictPrivatePlanFarmingPool = sdkerrors.Register(ModuleName, 10, "the address is already in use, please use a different plan name") + ErrInvalidStakingReservedAmount = sdkerrors.Register(ModuleName, 11, "staking reserved amount invariant broken") + ErrInvalidRemainingRewardsAmount = sdkerrors.Register(ModuleName, 12, "remaining rewards amount invariant broken") )