From d7ce071788fab3ce99b16ea6e4308b47877420e1 Mon Sep 17 00:00:00 2001 From: kogisin Date: Tue, 5 Oct 2021 18:25:35 +0900 Subject: [PATCH 01/10] docs: update stake description --- x/farming/client/cli/tx.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x/farming/client/cli/tx.go b/x/farming/client/cli/tx.go index 31466716..983b3869 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 plans that are available 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 { From 8166aab33715b9c36c677906f2c9d5a954899437 Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 6 Oct 2021 13:59:08 +0900 Subject: [PATCH 02/10] refactor: add more usage examples and update description --- x/farming/client/cli/tx.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/x/farming/client/cli/tx.go b/x/farming/client/cli/tx.go index 983b3869..24ffebfa 100644 --- a/x/farming/client/cli/tx.go +++ b/x/farming/client/cli/tx.go @@ -193,11 +193,11 @@ func NewStakeCmd() *cobra.Command { Long: strings.TrimSpace( fmt.Sprintf(`Stake coins. -To get farming rewards, you must stake coins that are defined in plans that 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 +$ %s tx %s stake 500poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4,500pool93E069B333B5ECEBFE24C6E1437E814003248E0DD7FF8B9F82119F4587449BA5 --from mykey `, version.AppName, types.ModuleName, version.AppName, types.ModuleName, @@ -235,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 { @@ -273,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 { @@ -334,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 { From 3aa5a5d9ba60b7cc8bfaa75477170ddc3c4f13b7 Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 6 Oct 2021 15:10:15 +0900 Subject: [PATCH 03/10] chore: add more test cases, refactor codes, and rename suite.go to suite_test.go --- x/farming/client/testutil/cli_helpers.go | 13 +++ .../testutil/{suite.go => suite_test.go} | 109 ++++++++++++++---- x/farming/keeper/reward.go | 3 +- 3 files changed, 99 insertions(+), 26 deletions(-) rename x/farming/client/testutil/{suite.go => suite_test.go} (90%) diff --git a/x/farming/client/testutil/cli_helpers.go b/x/farming/client/testutil/cli_helpers.go index 9a371fb8..31cc6abc 100644 --- a/x/farming/client/testutil/cli_helpers.go +++ b/x/farming/client/testutil/cli_helpers.go @@ -78,3 +78,16 @@ func MsgStakeExec(clientCtx client.Context, from string, stakingCoins string, return clitestutil.ExecTestCLICmd(clientCtx, farmingcli.NewStakeCmd(), args) } + +// MsgAdvanceEpoch creates a transaction to advance epoch by 1. +func MsgAdvanceEpoch(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) +} diff --git a/x/farming/client/testutil/suite.go b/x/farming/client/testutil/suite_test.go similarity index 90% rename from x/farming/client/testutil/suite.go rename to x/farming/client/testutil/suite_test.go index 8882c2a5..82c4c19b 100644 --- a/x/farming/client/testutil/suite.go +++ b/x/farming/client/testutil/suite_test.go @@ -39,6 +39,9 @@ type IntegrationTestSuite struct { func (s *IntegrationTestSuite) SetupTest() { s.T().Log("setting up integration test suite") + // enable advance epoch + farmingkeeper.EnableAdvanceEpoch = true + db := tmdb.NewMemDB() cfg := NewConfig(db) cfg.NumValidators = 1 @@ -406,24 +409,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 +471,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 +486,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 +536,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 +545,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 +553,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 +561,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) - // 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 = MsgAdvanceEpoch( + val.ClientCtx, + val.Address.String(), + ) + s.Require().NoError(err) + + // advance epoch by 1 + _, err = MsgAdvanceEpoch( + val.ClientCtx, + val.Address.String(), + ) + s.Require().NoError(err) testCases := []struct { name string @@ -555,24 +594,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{}, 1, + 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{}, 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, }, 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) From 5bf8622d0413a6f29760edd23932bda1bf5796cc Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 6 Oct 2021 15:12:29 +0900 Subject: [PATCH 04/10] docs: update the link --- x/farming/client/cli/tx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/farming/client/cli/tx.go b/x/farming/client/cli/tx.go index 24ffebfa..069763e4 100644 --- a/x/farming/client/cli/tx.go +++ b/x/farming/client/cli/tx.go @@ -377,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= From 93c00c481640b078759b50dfbc2bcf204b491a9d Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 6 Oct 2021 15:30:03 +0900 Subject: [PATCH 05/10] feat: increase code coverage --- x/farming/keeper/reward_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/x/farming/keeper/reward_test.go b/x/farming/keeper/reward_test.go index 3209037e..fb015193 100644 --- a/x/farming/keeper/reward_test.go +++ b/x/farming/keeper/reward_test.go @@ -288,12 +288,16 @@ func (suite *KeeperTestSuite) TestHarvest() { suite.keeper.SetPlan(suite.ctx, plan) } + // should return staking not exists + err := suite.keeper.Harvest(suite.ctx, suite.addrs[0], []string{denom1}) + suite.Require().Error(err) + 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]) From 46313bf5495381784a12269ba300deebab4c9224 Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 6 Oct 2021 16:30:24 +0900 Subject: [PATCH 06/10] test: code coverage --- x/farming/keeper/reward_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/x/farming/keeper/reward_test.go b/x/farming/keeper/reward_test.go index fb015193..e54cadc8 100644 --- a/x/farming/keeper/reward_test.go +++ b/x/farming/keeper/reward_test.go @@ -288,9 +288,8 @@ func (suite *KeeperTestSuite) TestHarvest() { suite.keeper.SetPlan(suite.ctx, plan) } - // should return staking not exists err := suite.keeper.Harvest(suite.ctx, suite.addrs[0], []string{denom1}) - suite.Require().Error(err) + 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) From e77034a1cc2b41690acf940b7002b3616b8615c6 Mon Sep 17 00:00:00 2001 From: kogisin Date: Thu, 7 Oct 2021 16:22:49 +0900 Subject: [PATCH 07/10] test: change the file name since coverage counts lines --- x/farming/client/testutil/{suite_test.go => suite.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename x/farming/client/testutil/{suite_test.go => suite.go} (100%) diff --git a/x/farming/client/testutil/suite_test.go b/x/farming/client/testutil/suite.go similarity index 100% rename from x/farming/client/testutil/suite_test.go rename to x/farming/client/testutil/suite.go From 7654bd4599031809a0ce66d723600757155765a5 Mon Sep 17 00:00:00 2001 From: kogisin Date: Thu, 7 Oct 2021 17:25:41 +0900 Subject: [PATCH 08/10] revert: test lines --- x/farming/keeper/reward_test.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/x/farming/keeper/reward_test.go b/x/farming/keeper/reward_test.go index e54cadc8..3209037e 100644 --- a/x/farming/keeper/reward_test.go +++ b/x/farming/keeper/reward_test.go @@ -288,15 +288,12 @@ 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]) From 35253c6b77e3ecf161e269125bc07ecad3c88ce6 Mon Sep 17 00:00:00 2001 From: kogisin Date: Thu, 7 Oct 2021 18:32:43 +0900 Subject: [PATCH 09/10] feat: apply feedbacks --- x/farming/client/testutil/cli_helpers.go | 20 +++- x/farming/client/testutil/suite.go | 146 +++++++++-------------- 2 files changed, 74 insertions(+), 92 deletions(-) diff --git a/x/farming/client/testutil/cli_helpers.go b/x/farming/client/testutil/cli_helpers.go index 31cc6abc..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" @@ -79,8 +80,8 @@ func MsgStakeExec(clientCtx client.Context, from string, stakingCoins string, return clitestutil.ExecTestCLICmd(clientCtx, farmingcli.NewStakeCmd(), args) } -// MsgAdvanceEpoch creates a transaction to advance epoch by 1. -func MsgAdvanceEpoch(clientCtx client.Context, from string, +// MsgAdvanceEpochExec creates a transaction to advance epoch by 1. +func MsgAdvanceEpochExec(clientCtx client.Context, from string, extraAtgs ...string) (testutil.BufferWriter, error) { args := append([]string{ @@ -91,3 +92,18 @@ func MsgAdvanceEpoch(clientCtx client.Context, from string, 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 82c4c19b..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,7 +36,6 @@ type IntegrationTestSuite struct { func (s *IntegrationTestSuite) SetupTest() { s.T().Log("setting up integration test suite") - // enable advance epoch farmingkeeper.EnableAdvanceEpoch = true db := tmdb.NewMemDB() @@ -573,14 +569,14 @@ func (s *IntegrationTestSuite) TestNewHarvestCmd() { s.Require().NoError(err) // advance epoch by 1 - _, err = MsgAdvanceEpoch( + _, err = MsgAdvanceEpochExec( val.ClientCtx, val.Address.String(), ) s.Require().NoError(err) // advance epoch by 1 - _, err = MsgAdvanceEpoch( + _, err = MsgAdvanceEpochExec( val.ClientCtx, val.Address.String(), ) @@ -671,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 @@ -690,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() { @@ -1148,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() } From 98964c1120164e9f1ddb4b38c32491b0a7b2079e Mon Sep 17 00:00:00 2001 From: kogisin Date: Fri, 8 Oct 2021 12:48:22 +0900 Subject: [PATCH 10/10] chore: increase code coverage and remove unused sentinel error --- x/farming/keeper/reward_test.go | 5 ++++- x/farming/types/errors.go | 9 ++++----- 2 files changed, 8 insertions(+), 6 deletions(-) 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") )