From 96da8cd01bac950295f63ca3ed24accb103051b6 Mon Sep 17 00:00:00 2001 From: kogisin Date: Thu, 23 Sep 2021 20:47:11 +0900 Subject: [PATCH 1/9] feat: work in progress --- x/farming/keeper/proposal_handler.go | 2 + x/farming/keeper/proposal_handler_test.go | 278 +++++++++++----------- 2 files changed, 137 insertions(+), 143 deletions(-) diff --git a/x/farming/keeper/proposal_handler.go b/x/farming/keeper/proposal_handler.go index 6b1234a4..33daea03 100644 --- a/x/farming/keeper/proposal_handler.go +++ b/x/farming/keeper/proposal_handler.go @@ -103,6 +103,8 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd return sdkerrors.Wrapf(sdkerrors.ErrNotFound, "plan %d is not found", p.GetPlanId()) } + // TODO: handle chaing plan type here + switch plan := plan.(type) { case *types.FixedAmountPlan: if p.GetFarmingPoolAddress() != "" { diff --git a/x/farming/keeper/proposal_handler_test.go b/x/farming/keeper/proposal_handler_test.go index ed17111b..f1987efe 100644 --- a/x/farming/keeper/proposal_handler_test.go +++ b/x/farming/keeper/proposal_handler_test.go @@ -200,27 +200,19 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { } func (suite *KeeperTestSuite) TestUpdatePublicPlanProposal() { - addrs := app.AddTestAddrs(suite.app, suite.ctx, 2, sdk.NewInt(100_000_000)) - farmerAddr := addrs[0] - name := "test" - terminationAddr := sdk.AccAddress("terminationAddr") - coinWeights := sdk.NewDecCoins( - sdk.DecCoin{ - Denom: "poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4", - Amount: sdk.MustNewDecFromStr("1.0"), - }, - ) - - // add request proposal + // add public ratio plan addReq := &types.AddRequestProposal{ - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, - StartTime: types.ParseTime("2021-08-06T00:00:00Z"), - EndTime: types.ParseTime("2021-08-13T00:00:00Z"), - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), - EpochRatio: sdk.ZeroDec(), + Name: "publicTestPlan1", + FarmingPoolAddress: suite.addrs[0].String(), + TerminationAddress: suite.addrs[0].String(), + StakingCoinWeights: sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% + sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% + ), + StartTime: types.ParseTime("2021-08-01T00:00:00Z"), + EndTime: types.ParseTime("2021-08-30T00:00:00Z"), + EpochAmount: nil, + EpochRatio: sdk.NewDecWithPrec(10, 2), // 10% } addRequests := []*types.AddRequestProposal{addReq} @@ -238,37 +230,37 @@ func (suite *KeeperTestSuite) TestUpdatePublicPlanProposal() { err = keeper.HandlePublicPlanProposal(suite.ctx, suite.keeper, proposal) suite.Require().NoError(err) - _, found := suite.keeper.GetPlan(suite.ctx, uint64(1)) + plan, found := suite.keeper.GetPlan(suite.ctx, uint64(1)) suite.Require().Equal(true, found) - // case1 - startTime := types.ParseTime("2021-08-06T00:00:00Z") - endTime := types.ParseTime("2021-08-13T00:00:00Z") + startTime := plan.GetStartTime() + endTime := plan.GetEndTime() + // case1: happy case req := &types.UpdateRequestProposal{ - PlanId: uint64(1), - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, + PlanId: plan.GetId(), + Name: plan.GetName(), + FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), + TerminationAddress: plan.GetTerminationAddress().String(), + StakingCoinWeights: plan.GetStakingCoinWeights(), StartTime: &startTime, EndTime: &endTime, - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), - EpochRatio: sdk.ZeroDec(), + EpochAmount: nil, + EpochRatio: sdk.NewDecWithPrec(5, 2), // decrease to 5% } case1 := []*types.UpdateRequestProposal{req} - // case2 + // case2: plam id is 0 req = &types.UpdateRequestProposal{ PlanId: uint64(0), - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, + Name: plan.GetName(), + FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), + TerminationAddress: plan.GetTerminationAddress().String(), + StakingCoinWeights: plan.GetStakingCoinWeights(), StartTime: &startTime, EndTime: &endTime, - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), - EpochRatio: sdk.ZeroDec(), + EpochAmount: nil, + EpochRatio: plan.(*types.RatioPlan).EpochRatio, } case2 := []*types.UpdateRequestProposal{req} @@ -279,9 +271,9 @@ func (suite *KeeperTestSuite) TestUpdatePublicPlanProposal() { OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM`, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, + FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), + TerminationAddress: plan.GetTerminationAddress().String(), + StakingCoinWeights: plan.GetStakingCoinWeights(), StartTime: &startTime, EndTime: &endTime, EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), @@ -289,80 +281,80 @@ func (suite *KeeperTestSuite) TestUpdatePublicPlanProposal() { } case3 := []*types.UpdateRequestProposal{req} - // case4 - req = &types.UpdateRequestProposal{ - PlanId: uint64(1), - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: sdk.NewDecCoins(), - StartTime: &startTime, - EndTime: &endTime, - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), - EpochRatio: sdk.ZeroDec(), - } - case4 := []*types.UpdateRequestProposal{req} - - // case5 - req = &types.UpdateRequestProposal{ - PlanId: uint64(1), - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: sdk.NewDecCoins( - sdk.DecCoin{ - Denom: "poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4", - Amount: sdk.MustNewDecFromStr("0.1"), - }, - ), - StartTime: &startTime, - EndTime: &endTime, - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), - EpochRatio: sdk.ZeroDec(), - } - case5 := []*types.UpdateRequestProposal{req} - - // case6 - req = &types.UpdateRequestProposal{ - PlanId: uint64(1), - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, - StartTime: &endTime, - EndTime: &startTime, - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), - EpochRatio: sdk.ZeroDec(), - } - case6 := []*types.UpdateRequestProposal{req} - - // case7 - req = &types.UpdateRequestProposal{ - PlanId: uint64(1), - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, - StartTime: &startTime, - EndTime: &endTime, - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 1)), - EpochRatio: sdk.NewDec(1), - } - case7 := []*types.UpdateRequestProposal{req} - - // case8 - req = &types.UpdateRequestProposal{ - PlanId: uint64(1), - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, - StartTime: &startTime, - EndTime: &endTime, - EpochAmount: sdk.NewCoins(), - EpochRatio: sdk.ZeroDec(), - } - case8 := []*types.UpdateRequestProposal{req} + // // case4 + // req = &types.UpdateRequestProposal{ + // PlanId: uint64(1), + // Name: name, + // FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), + // TerminationAddress: plan.GetTerminationAddress().String(), + // StakingCoinWeights: sdk.NewDecCoins(), + // StartTime: &startTime, + // EndTime: &endTime, + // EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), + // EpochRatio: sdk.ZeroDec(), + // } + // case4 := []*types.UpdateRequestProposal{req} + + // // case5 + // req = &types.UpdateRequestProposal{ + // PlanId: uint64(1), + // Name: name, + // FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), + // TerminationAddress: plan.GetTerminationAddress().String(), + // StakingCoinWeights: sdk.NewDecCoins( + // sdk.DecCoin{ + // Denom: "poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4", + // Amount: sdk.MustNewDecFromStr("0.1"), + // }, + // ), + // StartTime: &startTime, + // EndTime: &endTime, + // EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), + // EpochRatio: sdk.ZeroDec(), + // } + // case5 := []*types.UpdateRequestProposal{req} + + // // case6 + // req = &types.UpdateRequestProposal{ + // PlanId: uint64(1), + // Name: name, + // FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), + // TerminationAddress: plan.GetTerminationAddress().String(), + // StakingCoinWeights: coinWeights, + // StartTime: &endTime, + // EndTime: &startTime, + // EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), + // EpochRatio: sdk.ZeroDec(), + // } + // case6 := []*types.UpdateRequestProposal{req} + + // // case7 + // req = &types.UpdateRequestProposal{ + // PlanId: uint64(1), + // Name: name, + // FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), + // TerminationAddress: plan.GetTerminationAddress().String(), + // StakingCoinWeights: coinWeights, + // StartTime: &startTime, + // EndTime: &endTime, + // EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 1)), + // EpochRatio: sdk.NewDec(1), + // } + // case7 := []*types.UpdateRequestProposal{req} + + // // case8 + // req = &types.UpdateRequestProposal{ + // PlanId: uint64(1), + // Name: name, + // FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), + // TerminationAddress: plan.GetTerminationAddress().String(), + // StakingCoinWeights: coinWeights, + // StartTime: &startTime, + // EndTime: &endTime, + // EpochAmount: sdk.NewCoins(), + // EpochRatio: sdk.ZeroDec(), + // } + // case8 := []*types.UpdateRequestProposal{req} for _, tc := range []struct { name string @@ -394,33 +386,33 @@ func (suite *KeeperTestSuite) TestUpdatePublicPlanProposal() { case3, sdkerrors.Wrapf(types.ErrInvalidPlanNameLength, "plan name cannot be longer than max length of %d", types.MaxNameLength), }, - { - "staking coin weights case #1", - case4, - sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "staking coin weights must not be empty"), - }, - { - "staking coin weights case #2", - case5, - sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "total weight must be 1"), - }, - { - "start time & end time case #1", - case6, - sdkerrors.Wrapf(types.ErrInvalidPlanEndTime, - "end time %s must be greater than start time %s", - types.ParseTime("2021-08-06T00:00:00Z"), types.ParseTime("2021-08-13T00:00:00Z")), - }, - { - "epoch amount & epoch ratio case #1", - case7, - sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "either epoch amount or epoch ratio should be provided"), - }, - { - "epoch amount & epoch ratio case #2", - case8, - sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "either epoch amount or epoch ratio must not be zero"), - }, + // { + // "staking coin weights case #1", + // case4, + // sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "staking coin weights must not be empty"), + // }, + // { + // "staking coin weights case #2", + // case5, + // sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "total weight must be 1"), + // }, + // { + // "start time & end time case #1", + // case6, + // sdkerrors.Wrapf(types.ErrInvalidPlanEndTime, + // "end time %s must be greater than start time %s", + // types.ParseTime("2021-08-06T00:00:00Z"), types.ParseTime("2021-08-13T00:00:00Z")), + // }, + // { + // "epoch amount & epoch ratio case #1", + // case7, + // sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "either epoch amount or epoch ratio should be provided"), + // }, + // { + // "epoch amount & epoch ratio case #2", + // case8, + // sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "either epoch amount or epoch ratio must not be zero"), + // }, } { suite.Run(tc.name, func() { proposal := &types.PublicPlanProposal{ @@ -436,7 +428,7 @@ func (suite *KeeperTestSuite) TestUpdatePublicPlanProposal() { err := keeper.HandlePublicPlanProposal(suite.ctx, suite.keeper, proposal) suite.Require().NoError(err) - _, found := suite.keeper.GetPlan(suite.ctx, uint64(1)) + _, found := suite.keeper.GetPlan(suite.ctx, tc.updateRequest[0].GetPlanId()) suite.Require().Equal(true, found) } else { suite.EqualError(err, tc.expectedErr.Error()) From 7797dd6097778b70bb42d721904c287438957318 Mon Sep 17 00:00:00 2001 From: kogisin Date: Fri, 24 Sep 2021 13:07:23 +0900 Subject: [PATCH 2/9] feat: add logic to change plan type if there is a update request proposal --- x/farming/keeper/proposal_handler.go | 60 ++++++++++++++++++---------- x/farming/types/proposal.go | 57 ++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 20 deletions(-) diff --git a/x/farming/keeper/proposal_handler.go b/x/farming/keeper/proposal_handler.go index 33daea03..d06ac9ec 100644 --- a/x/farming/keeper/proposal_handler.go +++ b/x/farming/keeper/proposal_handler.go @@ -45,12 +45,13 @@ func (k Keeper) AddPublicPlanProposal(ctx sdk.Context, proposals []*types.AddReq if err != nil { return err } + terminationAcc, err := sdk.AccAddressFromBech32(p.GetTerminationAddress()) if err != nil { return err } - if !p.EpochAmount.IsZero() && !p.EpochAmount.IsAnyNegative() { + if p.EpochAmount.IsAllPositive() { msg := types.NewMsgCreateFixedAmountPlan( p.GetName(), farmingPoolAddrAcc, @@ -68,7 +69,7 @@ func (k Keeper) AddPublicPlanProposal(ctx sdk.Context, proposals []*types.AddReq logger := k.Logger(ctx) logger.Info("created public fixed amount plan", "fixed_amount_plan", plan) - } else if !p.EpochRatio.IsZero() && !p.EpochRatio.IsNegative() && !p.EpochRatio.IsNil() { + } else if p.EpochRatio.IsPositive() { msg := types.NewMsgCreateRatioPlan( p.GetName(), farmingPoolAddrAcc, @@ -103,10 +104,13 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd return sdkerrors.Wrapf(sdkerrors.ErrNotFound, "plan %d is not found", p.GetPlanId()) } - // TODO: handle chaing plan type here + if p.EpochAmount.IsAllPositive() { + if p.GetName() != "" { + if err := plan.SetName(p.GetName()); err != nil { + return err + } + } - switch plan := plan.(type) { - case *types.FixedAmountPlan: if p.GetFarmingPoolAddress() != "" { farmingPoolAddrAcc, err := sdk.AccAddressFromBech32(p.GetFarmingPoolAddress()) if err != nil { @@ -145,12 +149,20 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd } } - if p.GetName() != "" { - plan.Name = p.GetName() - } - + // change the plan to fixed amount plan if p.GetEpochAmount() != nil { - plan.EpochAmount = p.GetEpochAmount() + basePlan := types.NewBasePlan( + plan.GetId(), + plan.GetName(), + plan.GetType(), + plan.GetFarmingPoolAddress().String(), + plan.GetTerminationAddress().String(), + plan.GetStakingCoinWeights(), + plan.GetStartTime(), + plan.GetEndTime(), + ) + + plan = types.NewFixedAmountPlan(basePlan, p.GetEpochAmount()) } k.SetPlan(ctx, plan) @@ -158,9 +170,11 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd logger := k.Logger(ctx) logger.Info("updated public fixed amount plan", "fixed_amount_plan", plan) - case *types.RatioPlan: - if err := plan.Validate(); err != nil { - return err + } else if p.EpochRatio.IsPositive() { + if p.GetName() != "" { + if err := plan.SetName(p.GetName()); err != nil { + return err + } } if p.GetFarmingPoolAddress() != "" { @@ -201,12 +215,20 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd } } - if p.GetName() != "" { - plan.Name = p.GetName() - } - + // change the plan to ratio plan if !p.EpochRatio.IsZero() { - plan.EpochRatio = p.EpochRatio + basePlan := types.NewBasePlan( + plan.GetId(), + plan.GetName(), + plan.GetType(), + plan.GetFarmingPoolAddress().String(), + plan.GetTerminationAddress().String(), + plan.GetStakingCoinWeights(), + plan.GetStartTime(), + plan.GetEndTime(), + ) + + plan = types.NewRatioPlan(basePlan, p.EpochRatio) } k.SetPlan(ctx, plan) @@ -214,8 +236,6 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd logger := k.Logger(ctx) logger.Info("updated public ratio plan", "ratio_plan", plan) - default: - return sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized plan type: %T", p) } } diff --git a/x/farming/types/proposal.go b/x/farming/types/proposal.go index 63f4fa36..d88637fc 100644 --- a/x/farming/types/proposal.go +++ b/x/farming/types/proposal.go @@ -2,6 +2,7 @@ package types import ( "fmt" + time "time" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" @@ -20,6 +21,7 @@ func init() { gov.RegisterProposalTypeCodec(&PublicPlanProposal{}, "cosmos-sdk/PublicPlanProposal") } +// NewPublicPlanProposal creates a new PublicPlanProposal object. func NewPublicPlanProposal( title string, description string, @@ -83,6 +85,29 @@ func (p PublicPlanProposal) String() string { `, p.Title, p.Description, p.AddRequestProposals, p.UpdateRequestProposals, p.DeleteRequestProposals) } +// NewAddRequestProposal creates a new AddRequestProposal object +func NewAddRequestProposal( + name string, + farmingPoolAddr string, + terminationAddr string, + stakingCoinWeights sdk.DecCoins, + startTime time.Time, + endTime time.Time, + epochAmount sdk.Coins, + epochRatio sdk.Dec, +) *AddRequestProposal { + return &AddRequestProposal{ + Name: name, + FarmingPoolAddress: farmingPoolAddr, + TerminationAddress: terminationAddr, + StakingCoinWeights: stakingCoinWeights, + StartTime: startTime, + EndTime: endTime, + EpochAmount: epochAmount, + EpochRatio: epochRatio, + } +} + func (p *AddRequestProposal) Validate() error { if len(p.Name) > MaxNameLength { return sdkerrors.Wrapf(ErrInvalidPlanNameLength, "plan name cannot be longer than max length of %d", MaxNameLength) @@ -114,6 +139,31 @@ func (p *AddRequestProposal) Validate() error { return nil } +// NewUpdateRequestProposal creates a new UpdateRequestProposal object. +func NewUpdateRequestProposal( + id uint64, + name string, + farmingPoolAddr string, + terminationAddr string, + stakingCoinWeights sdk.DecCoins, + startTime time.Time, + endTime time.Time, + epochAmount sdk.Coins, + epochRatio sdk.Dec, +) *UpdateRequestProposal { + return &UpdateRequestProposal{ + PlanId: id, + Name: name, + FarmingPoolAddress: farmingPoolAddr, + TerminationAddress: terminationAddr, + StakingCoinWeights: stakingCoinWeights, + StartTime: &startTime, + EndTime: &endTime, + EpochAmount: epochAmount, + EpochRatio: epochRatio, + } +} + func (p *UpdateRequestProposal) Validate() error { if p.PlanId == 0 { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid plan id: %d", p.PlanId) @@ -148,6 +198,13 @@ func (p *UpdateRequestProposal) Validate() error { return nil } +// NewDeleteRequestProposal creates a new DeleteRequestProposal object. +func NewDeleteRequestProposal(id uint64) *DeleteRequestProposal { + return &DeleteRequestProposal{ + PlanId: id, + } +} + func (p *DeleteRequestProposal) Validate() error { if p.PlanId == 0 { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid plan id: %d", p.PlanId) From 3b23aafacffa7641f818eb33f8d64dc2d3ccdade Mon Sep 17 00:00:00 2001 From: kogisin Date: Fri, 24 Sep 2021 14:00:17 +0900 Subject: [PATCH 3/9] test: add more cases --- x/farming/keeper/proposal_handler.go | 6 +- x/farming/keeper/proposal_handler_test.go | 691 +++++++++++----------- 2 files changed, 346 insertions(+), 351 deletions(-) diff --git a/x/farming/keeper/proposal_handler.go b/x/farming/keeper/proposal_handler.go index d06ac9ec..eb9d84b7 100644 --- a/x/farming/keeper/proposal_handler.go +++ b/x/farming/keeper/proposal_handler.go @@ -31,6 +31,7 @@ func HandlePublicPlanProposal(ctx sdk.Context, k Keeper, proposal *types.PublicP if err := types.ValidateName(plans); err != nil { return err } + if err := types.ValidateTotalEpochRatio(plans); err != nil { return err } @@ -149,7 +150,7 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd } } - // change the plan to fixed amount plan + // change the plan to fixed amount plan if an epoch amount exists if p.GetEpochAmount() != nil { basePlan := types.NewBasePlan( plan.GetId(), @@ -215,7 +216,7 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd } } - // change the plan to ratio plan + // change the plan to ratio plan if an epoch ratio exists if !p.EpochRatio.IsZero() { basePlan := types.NewBasePlan( plan.GetId(), @@ -235,7 +236,6 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd logger := k.Logger(ctx) logger.Info("updated public ratio plan", "ratio_plan", plan) - } } diff --git a/x/farming/keeper/proposal_handler_test.go b/x/farming/keeper/proposal_handler_test.go index f1987efe..79fe959c 100644 --- a/x/farming/keeper/proposal_handler_test.go +++ b/x/farming/keeper/proposal_handler_test.go @@ -4,124 +4,13 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" - "github.com/tendermint/farming/app" "github.com/tendermint/farming/x/farming/keeper" "github.com/tendermint/farming/x/farming/types" _ "github.com/stretchr/testify/suite" ) -func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { - addrs := app.AddTestAddrs(suite.app, suite.ctx, 2, sdk.NewInt(100_000_000)) - farmerAddr := addrs[0] - name := "test" - terminationAddr := sdk.AccAddress("terminationAddr") - coinWeights := sdk.NewDecCoins( - sdk.DecCoin{ - Denom: "poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4", - Amount: sdk.MustNewDecFromStr("1.0"), - }, - ) - - // case1 - req := &types.AddRequestProposal{ - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, - StartTime: types.ParseTime("2021-08-06T00:00:00Z"), - EndTime: types.ParseTime("2021-08-13T00:00:00Z"), - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), - EpochRatio: sdk.ZeroDec(), - } - case1 := []*types.AddRequestProposal{req} - - // case2 - req = &types.AddRequestProposal{ - Name: `OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM - OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM - OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM - OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM`, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, - StartTime: types.ParseTime("2021-08-06T00:00:00Z"), - EndTime: types.ParseTime("2021-08-13T00:00:00Z"), - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), - EpochRatio: sdk.ZeroDec(), - } - case2 := []*types.AddRequestProposal{req} - - // case3 - req = &types.AddRequestProposal{ - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: sdk.NewDecCoins(), - StartTime: types.ParseTime("2021-08-06T00:00:00Z"), - EndTime: types.ParseTime("2021-08-13T00:00:00Z"), - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), - EpochRatio: sdk.ZeroDec(), - } - case3 := []*types.AddRequestProposal{req} - - // case4 - req = &types.AddRequestProposal{ - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: sdk.NewDecCoins( - sdk.DecCoin{ - Denom: "poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4", - Amount: sdk.MustNewDecFromStr("0.1"), - }, - ), - StartTime: types.ParseTime("2021-08-06T00:00:00Z"), - EndTime: types.ParseTime("2021-08-13T00:00:00Z"), - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), - EpochRatio: sdk.ZeroDec(), - } - case4 := []*types.AddRequestProposal{req} - - // case5 - req = &types.AddRequestProposal{ - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, - StartTime: types.ParseTime("2021-08-13T00:00:00Z"), - EndTime: types.ParseTime("2021-08-06T00:00:00Z"), - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), - EpochRatio: sdk.ZeroDec(), - } - case5 := []*types.AddRequestProposal{req} - - // case6 - req = &types.AddRequestProposal{ - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, - StartTime: types.ParseTime("2021-08-06T00:00:00Z"), - EndTime: types.ParseTime("2021-08-13T00:00:00Z"), - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 1)), - EpochRatio: sdk.NewDec(1), - } - case6 := []*types.AddRequestProposal{req} - - // case7 - req = &types.AddRequestProposal{ - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, - StartTime: types.ParseTime("2021-08-06T00:00:00Z"), - EndTime: types.ParseTime("2021-08-13T00:00:00Z"), - EpochAmount: sdk.NewCoins(), - EpochRatio: sdk.ZeroDec(), - } - case7 := []*types.AddRequestProposal{req} - +func (suite *KeeperTestSuite) TestValidateAddPublicPlanProposal() { for _, tc := range []struct { name string addRequest []*types.AddRequestProposal @@ -129,7 +18,19 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { }{ { "happy case", - case1, + []*types.AddRequestProposal{types.NewAddRequestProposal( + "testPlan", + suite.addrs[0].String(), + suite.addrs[0].String(), + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), + sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), + ), + types.ParseTime("2021-08-01T00:00:00Z"), + types.ParseTime("2021-08-30T00:00:00Z"), + sdk.NewCoins(sdk.NewInt64Coin(denom3, 100_000_000)), + sdk.ZeroDec(), + )}, nil, }, { @@ -137,41 +38,110 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "proposal request must not be empty"), }, - { - "request case #2", - []*types.AddRequestProposal{}, - sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "proposal request must not be empty"), - }, { "name case #1", - case2, + []*types.AddRequestProposal{types.NewAddRequestProposal( + `OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM + OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM + OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM + OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM`, + suite.addrs[0].String(), + suite.addrs[0].String(), + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), + sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), + ), + types.ParseTime("2021-08-01T00:00:00Z"), + types.ParseTime("2021-08-30T00:00:00Z"), + sdk.NewCoins(sdk.NewInt64Coin(denom3, 100_000_000)), + sdk.ZeroDec(), + )}, sdkerrors.Wrapf(types.ErrInvalidPlanNameLength, "plan name cannot be longer than max length of %d", types.MaxNameLength), }, { "staking coin weights case #1", - case3, + []*types.AddRequestProposal{types.NewAddRequestProposal( + "testPlan", + suite.addrs[0].String(), + suite.addrs[0].String(), + sdk.NewDecCoins(), + types.ParseTime("2021-08-01T00:00:00Z"), + types.ParseTime("2021-08-30T00:00:00Z"), + sdk.NewCoins(sdk.NewInt64Coin(denom3, 100_000_000)), + sdk.ZeroDec(), + )}, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "staking coin weights must not be empty"), }, { "staking coin weights case #2", - case4, + []*types.AddRequestProposal{types.NewAddRequestProposal( + "testPlan", + suite.addrs[0].String(), + suite.addrs[0].String(), + sdk.NewDecCoins( + sdk.DecCoin{ + Denom: "poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4", + Amount: sdk.MustNewDecFromStr("0.1"), + }, + ), + types.ParseTime("2021-08-01T00:00:00Z"), + types.ParseTime("2021-08-30T00:00:00Z"), + sdk.NewCoins(sdk.NewInt64Coin(denom3, 100_000_000)), + sdk.ZeroDec(), + )}, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "total weight must be 1"), }, { "start time & end time case #1", - case5, + []*types.AddRequestProposal{types.NewAddRequestProposal( + "testPlan", + suite.addrs[0].String(), + suite.addrs[0].String(), + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), + sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), + ), + types.ParseTime("2021-08-13T00:00:00Z"), + types.ParseTime("2021-08-06T00:00:00Z"), + sdk.NewCoins(sdk.NewInt64Coin(denom3, 100_000_000)), + sdk.ZeroDec(), + )}, sdkerrors.Wrapf(types.ErrInvalidPlanEndTime, "end time %s must be greater than start time %s", types.ParseTime("2021-08-06T00:00:00Z"), types.ParseTime("2021-08-13T00:00:00Z")), }, { "epoch amount & epoch ratio case #1", - case6, + []*types.AddRequestProposal{types.NewAddRequestProposal( + "testPlan", + suite.addrs[0].String(), + suite.addrs[0].String(), + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), + sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), + ), + types.ParseTime("2021-08-01T00:00:00Z"), + types.ParseTime("2021-08-30T00:00:00Z"), + sdk.NewCoins(sdk.NewInt64Coin(denom3, 1)), + sdk.NewDec(1), + )}, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "either epoch amount or epoch ratio should be provided"), }, { "epoch amount & epoch ratio case #2", - case7, + []*types.AddRequestProposal{types.NewAddRequestProposal( + "testPlan", + suite.addrs[0].String(), + suite.addrs[0].String(), + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), + sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), + ), + types.ParseTime("2021-08-01T00:00:00Z"), + types.ParseTime("2021-08-30T00:00:00Z"), + sdk.NewCoins(), + sdk.ZeroDec(), + )}, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "either epoch amount or epoch ratio must not be zero"), }, } { @@ -190,7 +160,6 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { suite.Require().NoError(err) _, found := suite.keeper.GetPlan(suite.ctx, uint64(1)) - // TODO: need to check each field same as expected suite.Require().Equal(true, found) } else { suite.EqualError(err, tc.expectedErr.Error()) @@ -199,171 +168,52 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { } } -func (suite *KeeperTestSuite) TestUpdatePublicPlanProposal() { - // add public ratio plan - addReq := &types.AddRequestProposal{ - Name: "publicTestPlan1", - FarmingPoolAddress: suite.addrs[0].String(), - TerminationAddress: suite.addrs[0].String(), - StakingCoinWeights: sdk.NewDecCoins( - sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% - sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% +func (suite *KeeperTestSuite) TestValidateUpdatePublicPlanProposal() { + // create a ratio public plan + addRequests := []*types.AddRequestProposal{ + types.NewAddRequestProposal( + "testPlan", + suite.addrs[0].String(), + suite.addrs[0].String(), + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% + sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% + ), + types.ParseTime("2021-08-01T00:00:00Z"), + types.ParseTime("2021-08-30T00:00:00Z"), + nil, + sdk.NewDecWithPrec(10, 2), // 10% ), - StartTime: types.ParseTime("2021-08-01T00:00:00Z"), - EndTime: types.ParseTime("2021-08-30T00:00:00Z"), - EpochAmount: nil, - EpochRatio: sdk.NewDecWithPrec(10, 2), // 10% } - addRequests := []*types.AddRequestProposal{addReq} - - proposal := &types.PublicPlanProposal{ - Title: "testTitle", - Description: "testDescription", - AddRequestProposals: addRequests, - UpdateRequestProposals: nil, - DeleteRequestProposals: nil, - } - - err := proposal.ValidateBasic() - suite.Require().NoError(err) - err = keeper.HandlePublicPlanProposal(suite.ctx, suite.keeper, proposal) + err := keeper.HandlePublicPlanProposal( + suite.ctx, + suite.keeper, + types.NewPublicPlanProposal("testTitle", "testDescription", addRequests, nil, nil), + ) suite.Require().NoError(err) plan, found := suite.keeper.GetPlan(suite.ctx, uint64(1)) suite.Require().Equal(true, found) - startTime := plan.GetStartTime() - endTime := plan.GetEndTime() - - // case1: happy case - req := &types.UpdateRequestProposal{ - PlanId: plan.GetId(), - Name: plan.GetName(), - FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), - TerminationAddress: plan.GetTerminationAddress().String(), - StakingCoinWeights: plan.GetStakingCoinWeights(), - StartTime: &startTime, - EndTime: &endTime, - EpochAmount: nil, - EpochRatio: sdk.NewDecWithPrec(5, 2), // decrease to 5% - } - case1 := []*types.UpdateRequestProposal{req} - - // case2: plam id is 0 - req = &types.UpdateRequestProposal{ - PlanId: uint64(0), - Name: plan.GetName(), - FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), - TerminationAddress: plan.GetTerminationAddress().String(), - StakingCoinWeights: plan.GetStakingCoinWeights(), - StartTime: &startTime, - EndTime: &endTime, - EpochAmount: nil, - EpochRatio: plan.(*types.RatioPlan).EpochRatio, - } - case2 := []*types.UpdateRequestProposal{req} - - // case3 - req = &types.UpdateRequestProposal{ - PlanId: uint64(1), - Name: `OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM - OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM - OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM - OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM`, - FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), - TerminationAddress: plan.GetTerminationAddress().String(), - StakingCoinWeights: plan.GetStakingCoinWeights(), - StartTime: &startTime, - EndTime: &endTime, - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), - EpochRatio: sdk.ZeroDec(), - } - case3 := []*types.UpdateRequestProposal{req} - - // // case4 - // req = &types.UpdateRequestProposal{ - // PlanId: uint64(1), - // Name: name, - // FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), - // TerminationAddress: plan.GetTerminationAddress().String(), - // StakingCoinWeights: sdk.NewDecCoins(), - // StartTime: &startTime, - // EndTime: &endTime, - // EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), - // EpochRatio: sdk.ZeroDec(), - // } - // case4 := []*types.UpdateRequestProposal{req} - - // // case5 - // req = &types.UpdateRequestProposal{ - // PlanId: uint64(1), - // Name: name, - // FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), - // TerminationAddress: plan.GetTerminationAddress().String(), - // StakingCoinWeights: sdk.NewDecCoins( - // sdk.DecCoin{ - // Denom: "poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4", - // Amount: sdk.MustNewDecFromStr("0.1"), - // }, - // ), - // StartTime: &startTime, - // EndTime: &endTime, - // EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), - // EpochRatio: sdk.ZeroDec(), - // } - // case5 := []*types.UpdateRequestProposal{req} - - // // case6 - // req = &types.UpdateRequestProposal{ - // PlanId: uint64(1), - // Name: name, - // FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), - // TerminationAddress: plan.GetTerminationAddress().String(), - // StakingCoinWeights: coinWeights, - // StartTime: &endTime, - // EndTime: &startTime, - // EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), - // EpochRatio: sdk.ZeroDec(), - // } - // case6 := []*types.UpdateRequestProposal{req} - - // // case7 - // req = &types.UpdateRequestProposal{ - // PlanId: uint64(1), - // Name: name, - // FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), - // TerminationAddress: plan.GetTerminationAddress().String(), - // StakingCoinWeights: coinWeights, - // StartTime: &startTime, - // EndTime: &endTime, - // EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 1)), - // EpochRatio: sdk.NewDec(1), - // } - // case7 := []*types.UpdateRequestProposal{req} - - // // case8 - // req = &types.UpdateRequestProposal{ - // PlanId: uint64(1), - // Name: name, - // FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), - // TerminationAddress: plan.GetTerminationAddress().String(), - // StakingCoinWeights: coinWeights, - // StartTime: &startTime, - // EndTime: &endTime, - // EpochAmount: sdk.NewCoins(), - // EpochRatio: sdk.ZeroDec(), - // } - // case8 := []*types.UpdateRequestProposal{req} - for _, tc := range []struct { name string updateRequest []*types.UpdateRequestProposal expectedErr error }{ { - "happy case", - case1, + "happy case #1 - decrease epoch ratio to 5%", + []*types.UpdateRequestProposal{types.NewUpdateRequestProposal( + plan.GetId(), + plan.GetName(), + plan.GetFarmingPoolAddress().String(), + plan.GetTerminationAddress().String(), + plan.GetStakingCoinWeights(), + plan.GetStartTime(), + plan.GetEndTime(), + nil, + sdk.NewDecWithPrec(5, 2), + )}, nil, }, { @@ -371,48 +221,123 @@ func (suite *KeeperTestSuite) TestUpdatePublicPlanProposal() { nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "proposal request must not be empty"), }, - { - "request case #2", - []*types.UpdateRequestProposal{}, - sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "proposal request must not be empty"), - }, { "plan id case #1", - case2, + []*types.UpdateRequestProposal{types.NewUpdateRequestProposal( + uint64(0), + plan.GetName(), + plan.GetFarmingPoolAddress().String(), + plan.GetTerminationAddress().String(), + plan.GetStakingCoinWeights(), + plan.GetStartTime(), + plan.GetEndTime(), + nil, + plan.(*types.RatioPlan).EpochRatio, + )}, sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid plan id: %d", uint64(0)), }, { "name case #1", - case3, + []*types.UpdateRequestProposal{types.NewUpdateRequestProposal( + plan.GetId(), + `OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM + OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM + OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM + OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM`, // max length of name + plan.GetFarmingPoolAddress().String(), + plan.GetTerminationAddress().String(), + plan.GetStakingCoinWeights(), + plan.GetStartTime(), + plan.GetEndTime(), + nil, + plan.(*types.RatioPlan).EpochRatio, + )}, sdkerrors.Wrapf(types.ErrInvalidPlanNameLength, "plan name cannot be longer than max length of %d", types.MaxNameLength), }, - // { - // "staking coin weights case #1", - // case4, - // sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "staking coin weights must not be empty"), - // }, - // { - // "staking coin weights case #2", - // case5, - // sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "total weight must be 1"), - // }, - // { - // "start time & end time case #1", - // case6, - // sdkerrors.Wrapf(types.ErrInvalidPlanEndTime, - // "end time %s must be greater than start time %s", - // types.ParseTime("2021-08-06T00:00:00Z"), types.ParseTime("2021-08-13T00:00:00Z")), - // }, - // { - // "epoch amount & epoch ratio case #1", - // case7, - // sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "either epoch amount or epoch ratio should be provided"), - // }, - // { - // "epoch amount & epoch ratio case #2", - // case8, - // sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "either epoch amount or epoch ratio must not be zero"), - // }, + { + "staking coin weights case #1", + []*types.UpdateRequestProposal{types.NewUpdateRequestProposal( + plan.GetId(), + plan.GetName(), + plan.GetFarmingPoolAddress().String(), + plan.GetTerminationAddress().String(), + sdk.NewDecCoins(), + plan.GetStartTime(), + plan.GetEndTime(), + nil, + plan.(*types.RatioPlan).EpochRatio, + )}, + sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "staking coin weights must not be empty"), + }, + { + "staking coin weights case #2", + []*types.UpdateRequestProposal{types.NewUpdateRequestProposal( + plan.GetId(), + plan.GetName(), + plan.GetFarmingPoolAddress().String(), + plan.GetTerminationAddress().String(), + sdk.NewDecCoins( + sdk.DecCoin{ + Denom: "poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4", + Amount: sdk.MustNewDecFromStr("0.1"), + }, + ), + plan.GetStartTime(), + plan.GetEndTime(), + nil, + plan.(*types.RatioPlan).EpochRatio, + )}, + sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "total weight must be 1"), + }, + { + "start time & end time case #1", + []*types.UpdateRequestProposal{types.NewUpdateRequestProposal( + plan.GetId(), + plan.GetName(), + plan.GetFarmingPoolAddress().String(), + plan.GetTerminationAddress().String(), + plan.GetStakingCoinWeights(), + types.ParseTime("2021-08-13T00:00:00Z"), + types.ParseTime("2021-08-06T00:00:00Z"), + nil, + plan.(*types.RatioPlan).EpochRatio, + )}, + sdkerrors.Wrapf(types.ErrInvalidPlanEndTime, + "end time %s must be greater than start time %s", + types.ParseTime("2021-08-06T00:00:00Z"), types.ParseTime("2021-08-13T00:00:00Z")), + }, + { + "epoch amount & epoch ratio case #1", + []*types.UpdateRequestProposal{ + types.NewUpdateRequestProposal( + plan.GetId(), + plan.GetName(), + plan.GetFarmingPoolAddress().String(), + plan.GetTerminationAddress().String(), + plan.GetStakingCoinWeights(), + plan.GetStartTime(), + plan.GetEndTime(), + sdk.NewCoins(sdk.NewInt64Coin("stake", 100_000)), + plan.(*types.RatioPlan).EpochRatio, + )}, + sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "either epoch amount or epoch ratio should be provided"), + }, + { + "epoch amount & epoch ratio case #2", + []*types.UpdateRequestProposal{ + types.NewUpdateRequestProposal( + plan.GetId(), + plan.GetName(), + plan.GetFarmingPoolAddress().String(), + plan.GetTerminationAddress().String(), + plan.GetStakingCoinWeights(), + plan.GetStartTime(), + plan.GetEndTime(), + sdk.NewCoins(sdk.NewInt64Coin("stake", 0)), + sdk.ZeroDec(), + )}, + sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "either epoch amount or epoch ratio must not be zero"), + }, } { suite.Run(tc.name, func() { proposal := &types.PublicPlanProposal{ @@ -437,54 +362,124 @@ func (suite *KeeperTestSuite) TestUpdatePublicPlanProposal() { } } -func (suite *KeeperTestSuite) TestDeletePublicPlanProposal() { - addrs := app.AddTestAddrs(suite.app, suite.ctx, 2, sdk.NewInt(100_000_000)) - farmerAddr := addrs[0] - name := "test" - terminationAddr := sdk.AccAddress("terminationAddr") - coinWeights := sdk.NewDecCoins( - sdk.DecCoin{ - Denom: "poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4", - Amount: sdk.MustNewDecFromStr("1.0"), - }, +func (suite *KeeperTestSuite) TestValidateDeletePublicPlanProposal() { + // create a ratio public plan + addRequests := []*types.AddRequestProposal{types.NewAddRequestProposal( + "testPlan", + suite.addrs[0].String(), + suite.addrs[0].String(), + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% + sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% + ), + types.ParseTime("2021-08-01T00:00:00Z"), + types.ParseTime("2021-08-30T00:00:00Z"), + nil, + sdk.NewDecWithPrec(10, 2), // 10% + )} + + err := keeper.HandlePublicPlanProposal( + suite.ctx, + suite.keeper, + types.NewPublicPlanProposal("testTitle", "testDescription", addRequests, nil, nil), ) + suite.Require().NoError(err) - // add request proposal - addReq := &types.AddRequestProposal{ - Name: name, - FarmingPoolAddress: farmerAddr.String(), - TerminationAddress: terminationAddr.String(), - StakingCoinWeights: coinWeights, - StartTime: types.ParseTime("2021-08-06T00:00:00Z"), - EndTime: types.ParseTime("2021-08-13T00:00:00Z"), - EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), - EpochRatio: sdk.ZeroDec(), - } - addRequests := []*types.AddRequestProposal{addReq} + // should exist + _, found := suite.keeper.GetPlan(suite.ctx, uint64(1)) + suite.Require().Equal(true, found) - proposal := &types.PublicPlanProposal{ - Title: "testTitle", - Description: "testDescription", - AddRequestProposals: addRequests, - UpdateRequestProposals: nil, - DeleteRequestProposals: nil, - } + // delete the proposal + deleteRequests := []*types.DeleteRequestProposal{types.NewDeleteRequestProposal(uint64(1))} - err := proposal.ValidateBasic() + err = keeper.HandlePublicPlanProposal( + suite.ctx, + suite.keeper, + types.NewPublicPlanProposal("testTitle", "testDescription", nil, nil, deleteRequests), + ) suite.Require().NoError(err) - err = keeper.HandlePublicPlanProposal(suite.ctx, suite.keeper, proposal) + // shouldn't exist + _, found = suite.keeper.GetPlan(suite.ctx, uint64(1)) + suite.Require().Equal(false, found) +} + +func (suite *KeeperTestSuite) TestUpdatePlanType() { + // create a ratio public plan + addRequests := []*types.AddRequestProposal{ + types.NewAddRequestProposal( + "testPlan", + suite.addrs[0].String(), + suite.addrs[0].String(), + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% + sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% + ), + types.ParseTime("2021-08-01T00:00:00Z"), + types.ParseTime("2021-08-30T00:00:00Z"), + nil, + sdk.NewDecWithPrec(10, 2), // 10% + ), + } + + err := keeper.HandlePublicPlanProposal( + suite.ctx, + suite.keeper, + types.NewPublicPlanProposal("testTitle", "testDescription", addRequests, nil, nil), + ) suite.Require().NoError(err) - _, found := suite.keeper.GetPlan(suite.ctx, uint64(1)) + plan, found := suite.keeper.GetPlan(suite.ctx, uint64(1)) suite.Require().Equal(true, found) + suite.Require().Equal(plan.(*types.RatioPlan).EpochRatio, sdk.NewDecWithPrec(10, 2)) + + // update the ratio plan to fixed amount plan type + updateRequests := []*types.UpdateRequestProposal{ + types.NewUpdateRequestProposal( + plan.GetId(), + plan.GetName(), + plan.GetFarmingPoolAddress().String(), + plan.GetTerminationAddress().String(), + plan.GetStakingCoinWeights(), + plan.GetStartTime(), + plan.GetEndTime(), + sdk.NewCoins(sdk.NewInt64Coin("stake", 100_000)), + sdk.ZeroDec(), + )} + + err = keeper.HandlePublicPlanProposal( + suite.ctx, + suite.keeper, + types.NewPublicPlanProposal("testTitle", "testDescription", nil, updateRequests, nil), + ) + suite.Require().NoError(err) - // delete the proposal - req := &types.DeleteRequestProposal{ - PlanId: uint64(1), - } - proposals := []*types.DeleteRequestProposal{req} + plan, found = suite.keeper.GetPlan(suite.ctx, uint64(1)) + suite.Require().Equal(true, found) + suite.Require().Equal(plan.(*types.FixedAmountPlan).EpochAmount, sdk.NewCoins(sdk.NewInt64Coin("stake", 100_000))) + + // update the fixed amount plan back to ratio plan + updateRequests = []*types.UpdateRequestProposal{ + types.NewUpdateRequestProposal( + plan.GetId(), + plan.GetName(), + plan.GetFarmingPoolAddress().String(), + plan.GetTerminationAddress().String(), + plan.GetStakingCoinWeights(), + plan.GetStartTime(), + plan.GetEndTime(), + nil, + sdk.NewDecWithPrec(7, 2), // 7% + )} - err = suite.keeper.DeletePublicPlanProposal(suite.ctx, proposals) + err = keeper.HandlePublicPlanProposal( + suite.ctx, + suite.keeper, + types.NewPublicPlanProposal("testTitle", "testDescription", nil, updateRequests, nil), + ) suite.Require().NoError(err) + + plan, found = suite.keeper.GetPlan(suite.ctx, uint64(1)) + suite.Require().Equal(true, found) + suite.Require().Equal(plan.(*types.RatioPlan).EpochRatio, sdk.NewDecWithPrec(7, 2)) } From cb3635cf2714a48503ff4ab46026929ba0b90de3 Mon Sep 17 00:00:00 2001 From: kogisin Date: Fri, 24 Sep 2021 14:13:20 +0900 Subject: [PATCH 4/9] chore: improve code coverage and update nil check to IsAllPositive --- x/farming/keeper/proposal_handler.go | 9 +++++---- x/farming/types/proposal.go | 3 +++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/x/farming/keeper/proposal_handler.go b/x/farming/keeper/proposal_handler.go index eb9d84b7..3934a2a0 100644 --- a/x/farming/keeper/proposal_handler.go +++ b/x/farming/keeper/proposal_handler.go @@ -108,7 +108,7 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd if p.EpochAmount.IsAllPositive() { if p.GetName() != "" { if err := plan.SetName(p.GetName()); err != nil { - return err + return err // nolint:errcheck } } @@ -151,7 +151,7 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd } // change the plan to fixed amount plan if an epoch amount exists - if p.GetEpochAmount() != nil { + if p.GetEpochAmount().IsAllPositive() { basePlan := types.NewBasePlan( plan.GetId(), plan.GetName(), @@ -174,7 +174,7 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd } else if p.EpochRatio.IsPositive() { if p.GetName() != "" { if err := plan.SetName(p.GetName()); err != nil { - return err + return err // nolint:errcheck } } @@ -217,7 +217,7 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd } // change the plan to ratio plan if an epoch ratio exists - if !p.EpochRatio.IsZero() { + if p.EpochRatio.IsPositive() { basePlan := types.NewBasePlan( plan.GetId(), plan.GetName(), @@ -236,6 +236,7 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd logger := k.Logger(ctx) logger.Info("updated public ratio plan", "ratio_plan", plan) + } } diff --git a/x/farming/types/proposal.go b/x/farming/types/proposal.go index d88637fc..18c74e79 100644 --- a/x/farming/types/proposal.go +++ b/x/farming/types/proposal.go @@ -86,6 +86,7 @@ func (p PublicPlanProposal) String() string { } // NewAddRequestProposal creates a new AddRequestProposal object +// nolint:interfacer func NewAddRequestProposal( name string, farmingPoolAddr string, @@ -140,6 +141,7 @@ func (p *AddRequestProposal) Validate() error { } // NewUpdateRequestProposal creates a new UpdateRequestProposal object. +// nolint:interfacer func NewUpdateRequestProposal( id uint64, name string, @@ -199,6 +201,7 @@ func (p *UpdateRequestProposal) Validate() error { } // NewDeleteRequestProposal creates a new DeleteRequestProposal object. +// nolint:interfacer func NewDeleteRequestProposal(id uint64) *DeleteRequestProposal { return &DeleteRequestProposal{ PlanId: id, From 67d3397788170985c5c027778868faa2e7b3b2ff Mon Sep 17 00:00:00 2001 From: kogisin Date: Fri, 24 Sep 2021 14:36:30 +0900 Subject: [PATCH 5/9] test: remove nolint comments --- x/farming/keeper/proposal_handler.go | 4 ++-- x/farming/types/proposal.go | 3 --- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/x/farming/keeper/proposal_handler.go b/x/farming/keeper/proposal_handler.go index 3934a2a0..06fb7452 100644 --- a/x/farming/keeper/proposal_handler.go +++ b/x/farming/keeper/proposal_handler.go @@ -108,7 +108,7 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd if p.EpochAmount.IsAllPositive() { if p.GetName() != "" { if err := plan.SetName(p.GetName()); err != nil { - return err // nolint:errcheck + return err } } @@ -174,7 +174,7 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd } else if p.EpochRatio.IsPositive() { if p.GetName() != "" { if err := plan.SetName(p.GetName()); err != nil { - return err // nolint:errcheck + return err } } diff --git a/x/farming/types/proposal.go b/x/farming/types/proposal.go index 18c74e79..d88637fc 100644 --- a/x/farming/types/proposal.go +++ b/x/farming/types/proposal.go @@ -86,7 +86,6 @@ func (p PublicPlanProposal) String() string { } // NewAddRequestProposal creates a new AddRequestProposal object -// nolint:interfacer func NewAddRequestProposal( name string, farmingPoolAddr string, @@ -141,7 +140,6 @@ func (p *AddRequestProposal) Validate() error { } // NewUpdateRequestProposal creates a new UpdateRequestProposal object. -// nolint:interfacer func NewUpdateRequestProposal( id uint64, name string, @@ -201,7 +199,6 @@ func (p *UpdateRequestProposal) Validate() error { } // NewDeleteRequestProposal creates a new DeleteRequestProposal object. -// nolint:interfacer func NewDeleteRequestProposal(id uint64) *DeleteRequestProposal { return &DeleteRequestProposal{ PlanId: id, From a67abc1983a2866c9abbf5030594bc52a5a51d73 Mon Sep 17 00:00:00 2001 From: kogisin Date: Fri, 24 Sep 2021 15:50:20 +0900 Subject: [PATCH 6/9] test: disable codecov patch --- .github/workflows/test.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b84b9dba..fbdfbbcf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -65,6 +65,12 @@ jobs: test-race: runs-on: ubuntu-latest timeout-minutes: 15 + status: + # Disable patch since it is noisy and not correct + patch: + default: + enabled: no + if_not_found: success steps: - uses: actions/checkout@v2 - uses: actions/setup-go@v2.1.3 From e9381d3ce3672ac00e60ab847ab5d1c2e8c8f0f8 Mon Sep 17 00:00:00 2001 From: kogisin Date: Fri, 24 Sep 2021 16:06:18 +0900 Subject: [PATCH 7/9] test: add codecov.yml and revert the prev commit --- .github/.codecov.yml | 28 ++++++++++++++++++++++++++++ .github/workflows/test.yml | 6 ------ 2 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 .github/.codecov.yml diff --git a/.github/.codecov.yml b/.github/.codecov.yml new file mode 100644 index 00000000..a02880f7 --- /dev/null +++ b/.github/.codecov.yml @@ -0,0 +1,28 @@ +# To validate: +# cat codecov.yml | curl --data-binary @- https://codecov.io/validate + +codecov: + notify: + require_ci_to_pass: yes + +coverage: + precision: 2 + round: down + range: "50...75" + + status: + project: + default: + threshold: 1 + unittest: + threshold: 1 + only_pulls: true + flags: + - "unittest" + # Disable patch since it is noisy and not correct + patch: + default: + enabled: no + if_not_found: success + +comment: false \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fbdfbbcf..b84b9dba 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -65,12 +65,6 @@ jobs: test-race: runs-on: ubuntu-latest timeout-minutes: 15 - status: - # Disable patch since it is noisy and not correct - patch: - default: - enabled: no - if_not_found: success steps: - uses: actions/checkout@v2 - uses: actions/setup-go@v2.1.3 From afb964efcf639c38fbd81b2a39c283d0385f7774 Mon Sep 17 00:00:00 2001 From: kogisin Date: Fri, 24 Sep 2021 16:17:11 +0900 Subject: [PATCH 8/9] test: update codecov.yml --- .github/.codecov.yml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.github/.codecov.yml b/.github/.codecov.yml index a02880f7..6f590683 100644 --- a/.github/.codecov.yml +++ b/.github/.codecov.yml @@ -8,21 +8,16 @@ codecov: coverage: precision: 2 round: down - range: "50...75" + range: "50...80" status: project: default: - threshold: 1 - unittest: - threshold: 1 - only_pulls: true - flags: - - "unittest" - # Disable patch since it is noisy and not correct + target: auto + threshold: 1% patch: default: - enabled: no + enabled: no # disable patch since it is noisy and not correct if_not_found: success comment: false \ No newline at end of file From f3b653b873a12386ee2b7c63744ef6f6a6ae7ac0 Mon Sep 17 00:00:00 2001 From: kogisin Date: Mon, 27 Sep 2021 17:54:09 +0900 Subject: [PATCH 9/9] chore: apply feedback --- x/farming/keeper/proposal_handler.go | 26 ++------------------------ x/farming/types/plan.go | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/x/farming/keeper/proposal_handler.go b/x/farming/keeper/proposal_handler.go index 06fb7452..49ab8366 100644 --- a/x/farming/keeper/proposal_handler.go +++ b/x/farming/keeper/proposal_handler.go @@ -152,18 +152,7 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd // change the plan to fixed amount plan if an epoch amount exists if p.GetEpochAmount().IsAllPositive() { - basePlan := types.NewBasePlan( - plan.GetId(), - plan.GetName(), - plan.GetType(), - plan.GetFarmingPoolAddress().String(), - plan.GetTerminationAddress().String(), - plan.GetStakingCoinWeights(), - plan.GetStartTime(), - plan.GetEndTime(), - ) - - plan = types.NewFixedAmountPlan(basePlan, p.GetEpochAmount()) + plan = types.NewFixedAmountPlan(plan.GetBasePlan(), p.GetEpochAmount()) } k.SetPlan(ctx, plan) @@ -218,18 +207,7 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd // change the plan to ratio plan if an epoch ratio exists if p.EpochRatio.IsPositive() { - basePlan := types.NewBasePlan( - plan.GetId(), - plan.GetName(), - plan.GetType(), - plan.GetFarmingPoolAddress().String(), - plan.GetTerminationAddress().String(), - plan.GetStakingCoinWeights(), - plan.GetStartTime(), - plan.GetEndTime(), - ) - - plan = types.NewRatioPlan(basePlan, p.EpochRatio) + plan = types.NewRatioPlan(plan.GetBasePlan(), p.EpochRatio) } k.SetPlan(ctx, plan) diff --git a/x/farming/types/plan.go b/x/farming/types/plan.go index 50647b50..b9aa2916 100644 --- a/x/farming/types/plan.go +++ b/x/farming/types/plan.go @@ -144,6 +144,22 @@ func (plan *BasePlan) SetDistributedCoins(distributedCoins sdk.Coins) error { return nil } +func (plan BasePlan) GetBasePlan() *BasePlan { + return &BasePlan{ + Id: plan.GetId(), + Name: plan.GetName(), + Type: plan.GetType(), + FarmingPoolAddress: plan.GetFarmingPoolAddress().String(), + TerminationAddress: plan.GetTerminationAddress().String(), + StakingCoinWeights: plan.GetStakingCoinWeights(), + StartTime: plan.GetStartTime(), + EndTime: plan.GetEndTime(), + Terminated: plan.GetTerminated(), + LastDistributionTime: plan.GetLastDistributionTime(), + DistributedCoins: plan.GetDistributedCoins(), + } +} + // Validate checks for errors on the Plan fields func (plan BasePlan) Validate() error { if plan.Type != PlanTypePrivate && plan.Type != PlanTypePublic { @@ -244,6 +260,8 @@ type PlanI interface { GetDistributedCoins() sdk.Coins SetDistributedCoins(sdk.Coins) error + GetBasePlan() *BasePlan + String() string Validate() error