From 16f10b719f1e488b2f5b7cdf608d1c2a8ef0e2fb Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 6 Oct 2021 15:38:46 +0900 Subject: [PATCH 1/6] docs: add comments for flags --- x/farming/client/cli/flags.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/x/farming/client/cli/flags.go b/x/farming/client/cli/flags.go index 3d0c11a1..0e008be9 100644 --- a/x/farming/client/cli/flags.go +++ b/x/farming/client/cli/flags.go @@ -14,6 +14,7 @@ const ( FlagAll = "all" ) +// flagSetPlans returns the FlagSet used for farming plan related opertations. func flagSetPlans() *flag.FlagSet { fs := flag.NewFlagSet("", flag.ContinueOnError) @@ -25,6 +26,7 @@ func flagSetPlans() *flag.FlagSet { return fs } +// flagSetStakings returns the FlagSet used for farmer's staking coin denom. func flagSetStakings() *flag.FlagSet { fs := flag.NewFlagSet("", flag.ContinueOnError) @@ -33,6 +35,7 @@ func flagSetStakings() *flag.FlagSet { return fs } +// flagSetRewards returns the FlagSet used for farmer's rewards. func flagSetRewards() *flag.FlagSet { fs := flag.NewFlagSet("", flag.ContinueOnError) @@ -41,6 +44,7 @@ func flagSetRewards() *flag.FlagSet { return fs } +// flagSetHarvest returns the FlagSet used for harvest all staking coin denoms. func flagSetHarvest() *flag.FlagSet { fs := flag.NewFlagSet("", flag.ContinueOnError) From 02c12d34374818f1ec2e36215b5df27086700dfc Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 6 Oct 2021 20:01:53 +0900 Subject: [PATCH 2/6] docs: update comments --- x/farming/client/cli/query.go | 8 +++++++- x/farming/client/cli/tx.go | 8 +++++++- x/farming/client/cli/utils.go | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/x/farming/client/cli/query.go b/x/farming/client/cli/query.go index bce6c783..eb5efa34 100644 --- a/x/farming/client/cli/query.go +++ b/x/farming/client/cli/query.go @@ -39,10 +39,10 @@ func GetQueryCmd() *cobra.Command { GetCmdQueryRewards(), GetCmdQueryCurrentEpochDays(), ) - return farmingQueryCmd } +// GetCmdQueryParams implements the query params command. func GetCmdQueryParams() *cobra.Command { cmd := &cobra.Command{ Use: "params", @@ -78,6 +78,7 @@ $ %s query %s params return cmd } +// GetCmdQueryPlans implements the query all plans command. func GetCmdQueryPlans() *cobra.Command { cmd := &cobra.Command{ Use: "plans [optional flags]", @@ -148,6 +149,7 @@ $ %s query %s plans --staking-coin-denom poolD35A0CC16EE598F90B044CE296A405BA9C3 return cmd } +// GetCmdQueryPlan implements the query the particular plan command. func GetCmdQueryPlan() *cobra.Command { cmd := &cobra.Command{ Use: "plan [plan-id]", @@ -190,6 +192,7 @@ $ %s query %s plan return cmd } +// GetCmdQueryStakings implements the query all stakings command. func GetCmdQueryStakings() *cobra.Command { bech32PrefixAccAddr := sdk.GetConfig().GetBech32AccountAddrPrefix() @@ -242,6 +245,7 @@ $ %s query %s stakings %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj --staking-coin- return cmd } +// GetCmdQueryTotalStakings implements the query total staking amounts for a staking coin denom command. func GetCmdQueryTotalStakings() *cobra.Command { cmd := &cobra.Command{ Use: "total-stakings [staking-coin-denom]", @@ -284,6 +288,7 @@ $ %s query %s total-stakings poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D return cmd } +// GetCmdQueryRewards implements the query all rewards for a farmer command. func GetCmdQueryRewards() *cobra.Command { bech32PrefixAccAddr := sdk.GetConfig().GetBech32AccountAddrPrefix() @@ -336,6 +341,7 @@ $ %s query %s rewards %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj --staking-coin-d return cmd } +// GetCmdQueryCurrentEpochDays implements the query current epoch days command. func GetCmdQueryCurrentEpochDays() *cobra.Command { cmd := &cobra.Command{ Use: "current-epoch-days", diff --git a/x/farming/client/cli/tx.go b/x/farming/client/cli/tx.go index 31466716..236fb1c1 100644 --- a/x/farming/client/cli/tx.go +++ b/x/farming/client/cli/tx.go @@ -46,6 +46,7 @@ func GetTxCmd() *cobra.Command { return farmingTxCmd } +// NewCreateFixedAmountPlanCmd implements the create a fixed amount plan command handler. func NewCreateFixedAmountPlanCmd() *cobra.Command { cmd := &cobra.Command{ Use: "create-private-fixed-plan [plan-file]", @@ -118,6 +119,7 @@ Description for the parameters: return cmd } +// NewCreateRatioPlanCmd implements the create a ratio plan command handler. func NewCreateRatioPlanCmd() *cobra.Command { cmd := &cobra.Command{ Use: "create-private-ratio-plan [plan-file]", @@ -185,6 +187,7 @@ Description for the parameters: return cmd } +// NewStakeCmd implements the stake coin(s) command handler. func NewStakeCmd() *cobra.Command { cmd := &cobra.Command{ Use: "stake [amount]", @@ -225,6 +228,7 @@ $ %s tx %s stake 1000poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C return cmd } +// NewUnstakeCmd implements the unstake coin(s) command handler. func NewUnstakeCmd() *cobra.Command { cmd := &cobra.Command{ Use: "unstake [amount]", @@ -265,6 +269,7 @@ $ %s tx %s unstake 500poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70 return cmd } +// NewHarvestCmd implements the harvest rewards command handler. func NewHarvestCmd() *cobra.Command { cmd := &cobra.Command{ Use: "harvest [staking-coin-denoms]", @@ -328,6 +333,7 @@ $ %s tx %s harvest --all --from mykey return cmd } +// NewAdvanceEpochCmd implements the advance epoch by 1 command handler. func NewAdvanceEpochCmd() *cobra.Command { cmd := &cobra.Command{ Use: "advance-epoch", @@ -352,7 +358,7 @@ func NewAdvanceEpochCmd() *cobra.Command { return cmd } -// GetCmdSubmitPublicPlanProposal implements a command handler for submitting a public farming plan transaction to create, update, and delete plan. +// GetCmdSubmitPublicPlanProposal implements the create/update/delete public farming plan command handler. func GetCmdSubmitPublicPlanProposal() *cobra.Command { cmd := &cobra.Command{ Use: "public-farming-plan [proposal-file] [flags]", diff --git a/x/farming/client/cli/utils.go b/x/farming/client/cli/utils.go index e87fd81d..f02c998d 100644 --- a/x/farming/client/cli/utils.go +++ b/x/farming/client/cli/utils.go @@ -77,6 +77,7 @@ func ParsePublicPlanProposal(cdc codec.JSONCodec, proposalFile string) (types.Pu return proposal, nil } +// String returns a human readable string representation of the request. func (req PrivateFixedPlanRequest) String() string { result, err := json.Marshal(&req) if err != nil { @@ -85,6 +86,7 @@ func (req PrivateFixedPlanRequest) String() string { return string(result) } +// String returns a human readable string representation of the request. func (req PrivateRatioPlanRequest) String() string { result, err := json.Marshal(&req) if err != nil { From df104f1d61bda97cde020b7fa1ef94540e68d5c6 Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 6 Oct 2021 20:08:19 +0900 Subject: [PATCH 3/6] docs: leave proper comments --- x/farming/client/proposal_handler.go | 3 ++- x/farming/client/rest/rest.go | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/x/farming/client/proposal_handler.go b/x/farming/client/proposal_handler.go index a8d00a97..be0880b0 100644 --- a/x/farming/client/proposal_handler.go +++ b/x/farming/client/proposal_handler.go @@ -7,7 +7,8 @@ import ( "github.com/tendermint/farming/x/farming/client/rest" ) -// ProposalHandler is the public plan creation handler. +// ProposalHandler is the public plan command handler. +// Note that rest.ProposalRESTHandler will be deprecated in the future. var ( ProposalHandler = govclient.NewProposalHandler(cli.GetCmdSubmitPublicPlanProposal, rest.ProposalRESTHandler) ) diff --git a/x/farming/client/rest/rest.go b/x/farming/client/rest/rest.go index fdf6ddf9..d77eda04 100644 --- a/x/farming/client/rest/rest.go +++ b/x/farming/client/rest/rest.go @@ -7,9 +7,6 @@ import ( govrest "github.com/cosmos/cosmos-sdk/x/gov/client/rest" ) -// TODO: not implemented yet; -// although this legacy REST API may not be needed, it needs for ProposalHandler; otherwise it throws panic when starting the chain - // ProposalRESTHandler returns a ProposalRESTHandler that exposes the farming plan proposal (add/update/delete) REST handler with a given sub-route. func ProposalRESTHandler(clientCtx client.Context) govrest.ProposalRESTHandler { return govrest.ProposalRESTHandler{ From e8c39f16f9c31482250a1a4b3dad089376d210d5 Mon Sep 17 00:00:00 2001 From: Hanjun Kim Date: Fri, 8 Oct 2021 18:22:35 +0900 Subject: [PATCH 4/6] chore: update comments for keeper --- x/farming/keeper/epoch.go | 18 ++++++--- x/farming/keeper/epoch_test.go | 9 ++--- x/farming/keeper/grpc_query.go | 11 ++++-- x/farming/keeper/keeper.go | 13 ++++--- x/farming/keeper/plan.go | 20 +++++----- x/farming/keeper/proposal_handler.go | 2 +- x/farming/keeper/reward.go | 58 +++++++++++++++++++++++++++- x/farming/keeper/staking.go | 57 +++++++++++++++++++++------ x/farming/keeper/staking_test.go | 6 +-- 9 files changed, 147 insertions(+), 47 deletions(-) diff --git a/x/farming/keeper/epoch.go b/x/farming/keeper/epoch.go index 49e2313b..f7e212ff 100644 --- a/x/farming/keeper/epoch.go +++ b/x/farming/keeper/epoch.go @@ -10,21 +10,25 @@ import ( "github.com/tendermint/farming/x/farming/types" ) -func (k Keeper) GetLastEpochTime(ctx sdk.Context) (time.Time, bool) { +// GetLastEpochTime returns the last time the epoch ended. +func (k Keeper) GetLastEpochTime(ctx sdk.Context) (t time.Time, found bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.LastEpochTimeKey) if bz == nil { - return time.Time{}, false + return } var ts gogotypes.Timestamp k.cdc.MustUnmarshal(bz, &ts) - t, err := gogotypes.TimestampFromProto(&ts) + var err error + t, err = gogotypes.TimestampFromProto(&ts) if err != nil { panic(err) } - return t, true + found = true + return } +// SetLastEpochTime sets the last time the epoch ended. func (k Keeper) SetLastEpochTime(ctx sdk.Context, t time.Time) { store := ctx.KVStore(k.storeKey) ts, err := gogotypes.TimestampProto(t) @@ -35,6 +39,8 @@ func (k Keeper) SetLastEpochTime(ctx sdk.Context, t time.Time) { store.Set(types.LastEpochTimeKey, bz) } +// AdvanceEpoch ends the current epoch. When an epoch ends, rewards +// are distributed and queued staking coins become staked. func (k Keeper) AdvanceEpoch(ctx sdk.Context) error { if err := k.AllocateRewards(ctx); err != nil { return err @@ -45,7 +51,7 @@ func (k Keeper) AdvanceEpoch(ctx sdk.Context) error { return nil } -// GetCurrentEpochDays returns the current epoch days. +// GetCurrentEpochDays returns the current epoch days(period). func (k Keeper) GetCurrentEpochDays(ctx sdk.Context) uint32 { var epochDays uint32 store := ctx.KVStore(k.storeKey) @@ -63,7 +69,7 @@ func (k Keeper) GetCurrentEpochDays(ctx sdk.Context) uint32 { return epochDays } -// SetCurrentEpochDays sets the current epoch days. +// SetCurrentEpochDays sets the current epoch days(period). func (k Keeper) SetCurrentEpochDays(ctx sdk.Context, epochDays uint32) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(&gogotypes.UInt32Value{Value: epochDays}) diff --git a/x/farming/keeper/epoch_test.go b/x/farming/keeper/epoch_test.go index dcc87e65..91be4b60 100644 --- a/x/farming/keeper/epoch_test.go +++ b/x/farming/keeper/epoch_test.go @@ -24,12 +24,11 @@ func (suite *KeeperTestSuite) TestLastEpochTime() { func (suite *KeeperTestSuite) TestFirstEpoch() { // The first epoch may run very quickly depending on when - // the farming module is deployed, + // the farming module was activated, // meaning that (block time) - (last epoch time) may be smaller - // than epoch_days parameter on the first epoch. + // than the current epoch_days for the first epoch. - params := suite.keeper.GetParams(suite.ctx) - suite.Require().Equal(uint32(1), params.NextEpochDays) + suite.Require().Equal(uint32(1), suite.keeper.GetCurrentEpochDays(suite.ctx)) suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-08-11T23:59:59Z")) farming.EndBlocker(suite.ctx, suite.keeper) @@ -39,7 +38,7 @@ func (suite *KeeperTestSuite) TestFirstEpoch() { suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-08-12T00:00:00Z")) farming.EndBlocker(suite.ctx, suite.keeper) t, _ := suite.keeper.GetLastEpochTime(suite.ctx) - suite.Require().True(t.After(lastEpochTime)) // Indicating that the epoch advanced. + suite.Require().True(t.After(lastEpochTime)) // Indicating that the epoch ended. } func (suite *KeeperTestSuite) TestEpochDays() { diff --git a/x/farming/keeper/grpc_query.go b/x/farming/keeper/grpc_query.go index 1cec3fe4..ebbbc4a1 100644 --- a/x/farming/keeper/grpc_query.go +++ b/x/farming/keeper/grpc_query.go @@ -77,7 +77,7 @@ func (k Querier) Plans(c context.Context, req *types.QueryPlansRequest) (*types. if err != nil { return false, err } - any, err := codectypes.NewAnyWithValue(plan) + planAny, err := types.PackPlan(plan) if err != nil { return false, err } @@ -114,7 +114,7 @@ func (k Querier) Plans(c context.Context, req *types.QueryPlansRequest) (*types. } if accumulate { - plans = append(plans, any) + plans = append(plans, planAny) } return true, nil @@ -138,14 +138,15 @@ func (k Querier) Plan(c context.Context, req *types.QueryPlanRequest) (*types.Qu return nil, status.Errorf(codes.NotFound, "plan %d not found", req.PlanId) } - any, err := codectypes.NewAnyWithValue(plan) + planAny, err := types.PackPlan(plan) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } - return &types.QueryPlanResponse{Plan: any}, nil + return &types.QueryPlanResponse{Plan: planAny}, nil } +// Stakings queries stakings for a farmer. func (k Querier) Stakings(c context.Context, req *types.QueryStakingsRequest) (*types.QueryStakingsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") @@ -191,6 +192,7 @@ func (k Querier) Stakings(c context.Context, req *types.QueryStakingsRequest) (* return resp, nil } +// TotalStakings queries total staking coin amount for a specific staking coin denom. func (k Querier) TotalStakings(c context.Context, req *types.QueryTotalStakingsRequest) (*types.QueryTotalStakingsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") @@ -212,6 +214,7 @@ func (k Querier) TotalStakings(c context.Context, req *types.QueryTotalStakingsR }, nil } +// Rewards queries accumulated rewards for a farmer. func (k Querier) Rewards(c context.Context, req *types.QueryRewardsRequest) (*types.QueryRewardsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") diff --git a/x/farming/keeper/keeper.go b/x/farming/keeper/keeper.go index 9482d39b..2e105e75 100644 --- a/x/farming/keeper/keeper.go +++ b/x/farming/keeper/keeper.go @@ -14,7 +14,10 @@ import ( ) var ( - enableAdvanceEpoch = "false" // set it to "true" using build flags to enable AdvanceEpoch msg handling. + enableAdvanceEpoch = "false" // Set this to "true" using build flags to enable AdvanceEpoch msg handling. + + // EnableAdvanceEpoch indicates whether msgServer accepts MsgAdvanceEpoch or not. + // Never set this to true in production mode. Doing that will expose serious attack vector. EnableAdvanceEpoch = false ) @@ -71,7 +74,7 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger { return ctx.Logger().With("module", "x/"+types.ModuleName) } -// GetParams gets the parameters for the farming module. +// GetParams returns the parameters for the farming module. func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { k.paramSpace.GetParamSet(ctx, ¶ms) return params @@ -82,15 +85,15 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { k.paramSpace.SetParamSet(ctx, ¶ms) } -// GetCodec return codec.Codec object used by the keeper +// GetCodec returns codec.Codec object used by the keeper> func (k Keeper) GetCodec() codec.BinaryCodec { return k.cdc } -// GetStakingReservePoolAcc returns module account for Staking Reserve Pool account +// GetStakingReservePoolAcc returns module account for the staking reserve pool account. func (k Keeper) GetStakingReservePoolAcc(ctx sdk.Context) sdk.AccAddress { // nolint:interfacer return types.StakingReserveAcc } -// GetRewardsReservePoolAcc returns temporary module account for Reward coins Reserve Pool account +// GetRewardsReservePoolAcc returns module account for the rewards reserve pool account. func (k Keeper) GetRewardsReservePoolAcc(ctx sdk.Context) sdk.AccAddress { // nolint:interfacer return types.RewardsReserveAcc } diff --git a/x/farming/keeper/plan.go b/x/farming/keeper/plan.go index 4897f0bf..12e98668 100644 --- a/x/farming/keeper/plan.go +++ b/x/farming/keeper/plan.go @@ -11,7 +11,7 @@ import ( "github.com/tendermint/farming/x/farming/types" ) -// NewPlan sets the next plan number to a given plan interface +// NewPlan sets the next plan number to a given PlanI. func (k Keeper) NewPlan(ctx sdk.Context, plan types.PlanI) types.PlanI { if err := plan.SetId(k.GetNextPlanIdWithUpdate(ctx)); err != nil { panic(err) @@ -20,7 +20,7 @@ func (k Keeper) NewPlan(ctx sdk.Context, plan types.PlanI) types.PlanI { return plan } -// GetPlan implements PlanI. +// GetPlan returns a plan for a given plan id. func (k Keeper) GetPlan(ctx sdk.Context, id uint64) (plan types.PlanI, found bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.GetPlanKey(id)) @@ -31,7 +31,7 @@ func (k Keeper) GetPlan(ctx sdk.Context, id uint64) (plan types.PlanI, found boo return k.decodePlan(bz), true } -// GetPlans returns all plans in the Keeper. +// GetPlans returns all plans in the store. func (k Keeper) GetPlans(ctx sdk.Context) (plans []types.PlanI) { k.IteratePlans(ctx, func(plan types.PlanI) (stop bool) { plans = append(plans, plan) @@ -41,7 +41,7 @@ func (k Keeper) GetPlans(ctx sdk.Context) (plans []types.PlanI) { return plans } -// SetPlan implements PlanI. +// SetPlan sets a plan for a given plan id. func (k Keeper) SetPlan(ctx sdk.Context, plan types.PlanI) { id := plan.GetId() store := ctx.KVStore(k.storeKey) @@ -54,7 +54,7 @@ func (k Keeper) SetPlan(ctx sdk.Context, plan types.PlanI) { store.Set(types.GetPlanKey(id), bz) } -// RemovePlan removes an plan for the plan mapper store. +// RemovePlan removes a plan from the store. // NOTE: this will cause supply invariant violation if called func (k Keeper) RemovePlan(ctx sdk.Context, plan types.PlanI) { id := plan.GetId() @@ -86,7 +86,7 @@ func (k Keeper) GetNextPlanIdWithUpdate(ctx sdk.Context) uint64 { return id } -// SetGlobalPlanId set the global Plan ID counter. +// SetGlobalPlanId sets the global Plan ID counter. func (k Keeper) SetGlobalPlanId(ctx sdk.Context, id uint64) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(&gogotypes.UInt64Value{Value: id}) @@ -124,13 +124,13 @@ func (k Keeper) decodePlan(bz []byte) types.PlanI { return acc } -// MarshalPlan protobuf serializes an Plan interface +// MarshalPlan serializes a plan. func (k Keeper) MarshalPlan(plan types.PlanI) ([]byte, error) { // nolint:interfacer return k.cdc.MarshalInterface(plan) } -// UnmarshalPlan returns an Plan interface from raw encoded plan -// bytes of a Proto-based Plan type +// UnmarshalPlan returns a plan from raw serialized +// bytes of a Proto-based Plan type. func (k Keeper) UnmarshalPlan(bz []byte) (plan types.PlanI, err error) { return plan, k.cdc.UnmarshalInterface(bz, &plan) } @@ -265,6 +265,8 @@ func (k Keeper) TerminatePlan(ctx sdk.Context, plan types.PlanI) error { return nil } +// GeneratePrivatePlanFarmingPoolAddress returns a unique account address +// of a farming pool for a private plan. func (k Keeper) GeneratePrivatePlanFarmingPoolAddress(ctx sdk.Context, name string) (sdk.AccAddress, error) { nextPlanId := k.GetGlobalPlanId(ctx) + 1 poolAcc := types.PrivatePlanFarmingPoolAddress(name, nextPlanId) diff --git a/x/farming/keeper/proposal_handler.go b/x/farming/keeper/proposal_handler.go index c84fe8b0..a3da501f 100644 --- a/x/farming/keeper/proposal_handler.go +++ b/x/farming/keeper/proposal_handler.go @@ -217,7 +217,7 @@ func (k Keeper) UpdatePublicPlanProposal(ctx sdk.Context, proposals []*types.Upd return nil } -// DeletePublicPlanProposal delets public plan proposal once the governance proposal is passed. +// DeletePublicPlanProposal deletes public plan proposal once the governance proposal is passed. func (k Keeper) DeletePublicPlanProposal(ctx sdk.Context, proposals []*types.DeleteRequestProposal) error { for _, p := range proposals { plan, found := k.GetPlan(ctx, p.GetPlanId()) diff --git a/x/farming/keeper/reward.go b/x/farming/keeper/reward.go index ea0bc077..cbbe54d6 100644 --- a/x/farming/keeper/reward.go +++ b/x/farming/keeper/reward.go @@ -9,6 +9,8 @@ import ( "github.com/tendermint/farming/x/farming/types" ) +// GetHistoricalRewards returns historical rewards for a given +// staking coin denom and an epoch number. func (k Keeper) GetHistoricalRewards(ctx sdk.Context, stakingCoinDenom string, epoch uint64) (rewards types.HistoricalRewards, found bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.GetHistoricalRewardsKey(stakingCoinDenom, epoch)) @@ -20,17 +22,24 @@ func (k Keeper) GetHistoricalRewards(ctx sdk.Context, stakingCoinDenom string, e return } +// SetHistoricalRewards sets historical rewards for a given +// staking coin denom and an epoch number. func (k Keeper) SetHistoricalRewards(ctx sdk.Context, stakingCoinDenom string, epoch uint64, rewards types.HistoricalRewards) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(&rewards) store.Set(types.GetHistoricalRewardsKey(stakingCoinDenom, epoch), bz) } +// DeleteHistoricalRewards deletes historical rewards for a given +// staking coin denom and an epoch number. func (k Keeper) DeleteHistoricalRewards(ctx sdk.Context, stakingCoinDenom string, epoch uint64) { store := ctx.KVStore(k.storeKey) store.Delete(types.GetHistoricalRewardsKey(stakingCoinDenom, epoch)) } +// IterateHistoricalRewards iterates through all historical rewards +// stored in the store and invokes callback function for each item. +// Stops the iteration when the callback function returns true. func (k Keeper) IterateHistoricalRewards(ctx sdk.Context, cb func(stakingCoinDenom string, epoch uint64, rewards types.HistoricalRewards) (stop bool)) { store := ctx.KVStore(k.storeKey) iter := sdk.KVStorePrefixIterator(store, types.HistoricalRewardsKeyPrefix) @@ -45,6 +54,8 @@ func (k Keeper) IterateHistoricalRewards(ctx sdk.Context, cb func(stakingCoinDen } } +// GetCurrentEpoch returns the current epoch number for a given +// staking coin denom. func (k Keeper) GetCurrentEpoch(ctx sdk.Context, stakingCoinDenom string) uint64 { store := ctx.KVStore(k.storeKey) bz := store.Get(types.GetCurrentEpochKey(stakingCoinDenom)) @@ -53,6 +64,8 @@ func (k Keeper) GetCurrentEpoch(ctx sdk.Context, stakingCoinDenom string) uint64 return val.GetValue() } +// SetCurrentEpoch sets the current epoch number for a given +// staking coin denom. func (k Keeper) SetCurrentEpoch(ctx sdk.Context, stakingCoinDenom string, currentEpoch uint64) { store := ctx.KVStore(k.storeKey) val := gogotypes.UInt64Value{Value: currentEpoch} @@ -60,6 +73,9 @@ func (k Keeper) SetCurrentEpoch(ctx sdk.Context, stakingCoinDenom string, curren store.Set(types.GetCurrentEpochKey(stakingCoinDenom), bz) } +// IterateCurrentEpochs iterates through all current epoch infos +// stored in the store and invokes callback function for each item. +// Stops the iteration when the callback function returns true. func (k Keeper) IterateCurrentEpochs(ctx sdk.Context, cb func(stakingCoinDenom string, currentEpoch uint64) (stop bool)) { store := ctx.KVStore(k.storeKey) iter := sdk.KVStorePrefixIterator(store, types.CurrentEpochKeyPrefix) @@ -74,6 +90,8 @@ func (k Keeper) IterateCurrentEpochs(ctx sdk.Context, cb func(stakingCoinDenom s } } +// GetOutstandingRewards returns outstanding rewards for a given +// staking coin denom. func (k Keeper) GetOutstandingRewards(ctx sdk.Context, stakingCoinDenom string) (rewards types.OutstandingRewards, found bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.GetOutstandingRewardsKey(stakingCoinDenom)) @@ -85,17 +103,24 @@ func (k Keeper) GetOutstandingRewards(ctx sdk.Context, stakingCoinDenom string) return } +// SetOutstandingRewards sets outstanding rewards for a given +// staking coin denom. func (k Keeper) SetOutstandingRewards(ctx sdk.Context, stakingCoinDenom string, rewards types.OutstandingRewards) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(&rewards) store.Set(types.GetOutstandingRewardsKey(stakingCoinDenom), bz) } +// DeleteOutstandingRewards deletes outstanding rewards for a given +// staking coin denom. func (k Keeper) DeleteOutstandingRewards(ctx sdk.Context, stakingCoinDenom string) { store := ctx.KVStore(k.storeKey) store.Delete(types.GetOutstandingRewardsKey(stakingCoinDenom)) } +// IterateOutstandingRewards iterates through all outstanding rewards +// stored in the store and invokes callback function for each item. +// Stops the iteration when the callback function returns true. func (k Keeper) IterateOutstandingRewards(ctx sdk.Context, cb func(stakingCoinDenom string, rewards types.OutstandingRewards) (stop bool)) { store := ctx.KVStore(k.storeKey) iter := sdk.KVStorePrefixIterator(store, types.OutstandingRewardsKeyPrefix) @@ -110,12 +135,18 @@ func (k Keeper) IterateOutstandingRewards(ctx sdk.Context, cb func(stakingCoinDe } } +// IncreaseOutstandingRewards increases outstanding rewards for a given +// staking coin denom by given amount. func (k Keeper) IncreaseOutstandingRewards(ctx sdk.Context, stakingCoinDenom string, amount sdk.DecCoins) { outstanding, _ := k.GetOutstandingRewards(ctx, stakingCoinDenom) outstanding.Rewards = outstanding.Rewards.Add(amount...) k.SetOutstandingRewards(ctx, stakingCoinDenom, outstanding) } +// DecreaseOutstandingRewards decreases outstanding rewards for a given +// staking coin denom by given amount. +// If the resulting outstanding rewards is zero, then the outstanding rewards +// will be deleted, not updated. func (k Keeper) DecreaseOutstandingRewards(ctx sdk.Context, stakingCoinDenom string, amount sdk.DecCoins) { outstanding, found := k.GetOutstandingRewards(ctx, stakingCoinDenom) if !found { @@ -129,6 +160,8 @@ func (k Keeper) DecreaseOutstandingRewards(ctx sdk.Context, stakingCoinDenom str } } +// CalculateRewards returns rewards accumulated until endingEpoch +// for a farmer for a given staking coin denom. func (k Keeper) CalculateRewards(ctx sdk.Context, farmerAcc sdk.AccAddress, stakingCoinDenom string, endingEpoch uint64) (rewards sdk.DecCoins) { staking, found := k.GetStaking(ctx, stakingCoinDenom, farmerAcc) if !found { @@ -142,6 +175,8 @@ func (k Keeper) CalculateRewards(ctx sdk.Context, farmerAcc sdk.AccAddress, stak return } +// Rewards returns truncated rewards accumulated until the current epoch +// for a farmer for a given staking coin denom. func (k Keeper) Rewards(ctx sdk.Context, farmerAcc sdk.AccAddress, stakingCoinDenom string) sdk.Coins { currentEpoch := k.GetCurrentEpoch(ctx, stakingCoinDenom) rewards := k.CalculateRewards(ctx, farmerAcc, stakingCoinDenom, currentEpoch-1) @@ -150,6 +185,8 @@ func (k Keeper) Rewards(ctx sdk.Context, farmerAcc sdk.AccAddress, stakingCoinDe return truncatedRewards } +// AllRewards returns truncated total rewards accumulated until the +// current epoch for a farmer. func (k Keeper) AllRewards(ctx sdk.Context, farmerAcc sdk.AccAddress) sdk.Coins { totalRewards := sdk.NewCoins() k.IterateStakingsByFarmer(ctx, farmerAcc, func(stakingCoinDenom string, staking types.Staking) (stop bool) { @@ -160,6 +197,10 @@ func (k Keeper) AllRewards(ctx sdk.Context, farmerAcc sdk.AccAddress) sdk.Coins return totalRewards } +// WithdrawRewards withdraws accumulated rewards for a farmer for a given +// staking coin denom. +// It decreases outstanding rewards and set the starting epoch of a +// staking. func (k Keeper) WithdrawRewards(ctx sdk.Context, farmerAcc sdk.AccAddress, stakingCoinDenom string) (sdk.Coins, error) { staking, found := k.GetStaking(ctx, stakingCoinDenom, farmerAcc) if !found { @@ -187,6 +228,7 @@ func (k Keeper) WithdrawRewards(ctx sdk.Context, farmerAcc sdk.AccAddress, staki return truncatedRewards, nil } +// WithdrawAllRewards withdraws all accumulated rewards for a farmer. func (k Keeper) WithdrawAllRewards(ctx sdk.Context, farmerAcc sdk.AccAddress) (sdk.Coins, error) { totalRewards := sdk.NewCoins() k.IterateStakingsByFarmer(ctx, farmerAcc, func(stakingCoinDenom string, staking types.Staking) (stop bool) { @@ -237,11 +279,16 @@ func (k Keeper) Harvest(ctx sdk.Context, farmerAcc sdk.AccAddress, stakingCoinDe return nil } +// AllocationInfo holds information about an allocation for a plan. type AllocationInfo struct { Plan types.PlanI Amount sdk.Coins } +// AllocationInfos returns allocation infos for the end +// of the current epoch. +// When total allocated coins for a farming pool exceeds the pool's +// balance, then allocation will not happen. func (k Keeper) AllocationInfos(ctx sdk.Context) []AllocationInfo { farmingPoolBalances := make(map[string]sdk.Coins) // farmingPoolAddress => sdk.Coins allocCoins := make(map[string]map[uint64]sdk.Coins) // farmingPoolAddress => (planId => sdk.Coins) @@ -301,6 +348,8 @@ func (k Keeper) AllocationInfos(ctx sdk.Context) []AllocationInfo { return allocInfos } +// AllocateRewards updates historical rewards and current epoch info +// based on the allocation infos. func (k Keeper) AllocateRewards(ctx sdk.Context) error { unitRewardsByDenom := map[string]sdk.DecCoins{} // (staking coin denom) => (unit rewards) @@ -366,7 +415,9 @@ func (k Keeper) AllocateRewards(ctx sdk.Context) error { return nil } -// ValidateRemainingRewardsAmount checks that the balance of the RewardPoolAddresses of all plans greater than the total amount of unwithdrawn reward coins in all reward objects +// ValidateRemainingRewardsAmount checks that the balance of the +// rewards reserve pool is greater than the total amount of +// unwithdrawn rewards. // TODO: correct comment above func (k Keeper) ValidateRemainingRewardsAmount(ctx sdk.Context) error { remainingRewards := sdk.NewCoins() @@ -384,6 +435,9 @@ func (k Keeper) ValidateRemainingRewardsAmount(ctx sdk.Context) error { return nil } +// ValidateOutstandingRewards checks that the balance of the +// rewards reserve pool is greater than the total amount of +// outstanding rewards. func (k Keeper) ValidateOutstandingRewards(ctx sdk.Context) error { totalOutstandingRewards := sdk.NewDecCoins() k.IterateOutstandingRewards(ctx, func(stakingCoinDenom string, rewards types.OutstandingRewards) (stop bool) { @@ -394,7 +448,7 @@ func (k Keeper) ValidateOutstandingRewards(ctx sdk.Context) error { rewardsReservePoolBalances := sdk.NewDecCoinsFromCoins(k.bankKeeper.GetAllBalances(ctx, k.GetRewardsReservePoolAcc(ctx))...) _, hasNeg := rewardsReservePoolBalances.SafeSub(totalOutstandingRewards) if hasNeg { - return types.ErrInvalidStakingReservedAmount // TODO: use different error type + return types.ErrInvalidRemainingRewardsAmount // TODO: use different error type } return nil diff --git a/x/farming/keeper/staking.go b/x/farming/keeper/staking.go index 3533e23e..8c293529 100644 --- a/x/farming/keeper/staking.go +++ b/x/farming/keeper/staking.go @@ -7,7 +7,7 @@ import ( "github.com/tendermint/farming/x/farming/types" ) -// GetStaking returns a specific staking identified by id. +// GetStaking returns a staking for given staking denom and farmer. func (k Keeper) GetStaking(ctx sdk.Context, stakingCoinDenom string, farmerAcc sdk.AccAddress) (staking types.Staking, found bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.GetStakingKey(stakingCoinDenom, farmerAcc)) @@ -19,7 +19,7 @@ func (k Keeper) GetStaking(ctx sdk.Context, stakingCoinDenom string, farmerAcc s return } -// SetStaking implements Staking. +// SetStaking sets a staking for given staking coin denom and farmer. func (k Keeper) SetStaking(ctx sdk.Context, stakingCoinDenom string, farmerAcc sdk.AccAddress, staking types.Staking) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(&staking) @@ -27,12 +27,16 @@ func (k Keeper) SetStaking(ctx sdk.Context, stakingCoinDenom string, farmerAcc s store.Set(types.GetStakingIndexKey(farmerAcc, stakingCoinDenom), []byte{}) } +// DeleteStaking deletes a staking for given staking coin denom and farmer. func (k Keeper) DeleteStaking(ctx sdk.Context, stakingCoinDenom string, farmerAcc sdk.AccAddress) { store := ctx.KVStore(k.storeKey) store.Delete(types.GetStakingKey(stakingCoinDenom, farmerAcc)) store.Delete(types.GetStakingIndexKey(farmerAcc, stakingCoinDenom)) } +// IterateStakings iterates through all stakings stored in the store +// and invokes callback function for each item. +// Stops the iteration when the callback function returns true. func (k Keeper) IterateStakings(ctx sdk.Context, cb func(stakingCoinDenom string, farmerAcc sdk.AccAddress, staking types.Staking) (stop bool)) { store := ctx.KVStore(k.storeKey) iter := sdk.KVStorePrefixIterator(store, types.StakingKeyPrefix) @@ -47,6 +51,9 @@ func (k Keeper) IterateStakings(ctx sdk.Context, cb func(stakingCoinDenom string } } +// IterateStakingsByFarmer iterates through all stakings by a farmer +// stored in the store and invokes callback function for each item. +// Stops the iteration when the callback function returns true. func (k Keeper) IterateStakingsByFarmer(ctx sdk.Context, farmerAcc sdk.AccAddress, cb func(stakingCoinDenom string, staking types.Staking) (stop bool)) { store := ctx.KVStore(k.storeKey) iter := sdk.KVStorePrefixIterator(store, types.GetStakingsByFarmerPrefix(farmerAcc)) @@ -60,6 +67,7 @@ func (k Keeper) IterateStakingsByFarmer(ctx sdk.Context, farmerAcc sdk.AccAddres } } +// GetAllStakedCoinsByFarmer returns all coins that are staked by a farmer. func (k Keeper) GetAllStakedCoinsByFarmer(ctx sdk.Context, farmerAcc sdk.AccAddress) sdk.Coins { stakedCoins := sdk.NewCoins() k.IterateStakingsByFarmer(ctx, farmerAcc, func(stakingCoinDenom string, staking types.Staking) (stop bool) { @@ -69,6 +77,8 @@ func (k Keeper) GetAllStakedCoinsByFarmer(ctx sdk.Context, farmerAcc sdk.AccAddr return stakedCoins } +// GetQueuedStaking returns a queued staking for given staking coin denom +// and farmer. func (k Keeper) GetQueuedStaking(ctx sdk.Context, stakingCoinDenom string, farmerAcc sdk.AccAddress) (queuedStaking types.QueuedStaking, found bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.GetQueuedStakingKey(stakingCoinDenom, farmerAcc)) @@ -80,15 +90,8 @@ func (k Keeper) GetQueuedStaking(ctx sdk.Context, stakingCoinDenom string, farme return } -func (k Keeper) GetAllQueuedStakedCoinsByFarmer(ctx sdk.Context, farmerAcc sdk.AccAddress) sdk.Coins { - stakedCoins := sdk.NewCoins() - k.IterateQueuedStakingsByFarmer(ctx, farmerAcc, func(stakingCoinDenom string, queuedStaking types.QueuedStaking) (stop bool) { - stakedCoins = stakedCoins.Add(sdk.NewCoin(stakingCoinDenom, queuedStaking.Amount)) - return false - }) - return stakedCoins -} - +// SetQueuedStaking sets a queued staking for given staking coin denom +// and farmer. func (k Keeper) SetQueuedStaking(ctx sdk.Context, stakingCoinDenom string, farmerAcc sdk.AccAddress, queuedStaking types.QueuedStaking) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(&queuedStaking) @@ -96,12 +99,17 @@ func (k Keeper) SetQueuedStaking(ctx sdk.Context, stakingCoinDenom string, farme store.Set(types.GetQueuedStakingIndexKey(farmerAcc, stakingCoinDenom), []byte{}) } +// DeleteQueuedStaking deletes a queued staking for given staking coin denom +// and farmer. func (k Keeper) DeleteQueuedStaking(ctx sdk.Context, stakingCoinDenom string, farmerAcc sdk.AccAddress) { store := ctx.KVStore(k.storeKey) store.Delete(types.GetQueuedStakingKey(stakingCoinDenom, farmerAcc)) store.Delete(types.GetQueuedStakingIndexKey(farmerAcc, stakingCoinDenom)) } +// IterateQueuedStakings iterates through all queued stakings stored in +// the store and invokes callback function for each item. +// Stops the iteration when the callback function returns true. func (k Keeper) IterateQueuedStakings(ctx sdk.Context, cb func(stakingCoinDenom string, farmerAcc sdk.AccAddress, queuedStaking types.QueuedStaking) (stop bool)) { store := ctx.KVStore(k.storeKey) iter := sdk.KVStorePrefixIterator(store, types.QueuedStakingKeyPrefix) @@ -116,6 +124,9 @@ func (k Keeper) IterateQueuedStakings(ctx sdk.Context, cb func(stakingCoinDenom } } +// IterateQueuedStakingsByFarmer iterates through all queued stakings +// by farmer stored in the store and invokes callback function for each item. +// Stops the iteration when the callback function returns true. func (k Keeper) IterateQueuedStakingsByFarmer(ctx sdk.Context, farmerAcc sdk.AccAddress, cb func(stakingCoinDenom string, queuedStaking types.QueuedStaking) (stop bool)) { store := ctx.KVStore(k.storeKey) iter := sdk.KVStorePrefixIterator(store, types.GetQueuedStakingByFarmerPrefix(farmerAcc)) @@ -129,6 +140,18 @@ func (k Keeper) IterateQueuedStakingsByFarmer(ctx sdk.Context, farmerAcc sdk.Acc } } +// GetAllQueuedCoinsByFarmer returns all coins that are queued for staking +// by a farmer. +func (k Keeper) GetAllQueuedCoinsByFarmer(ctx sdk.Context, farmerAcc sdk.AccAddress) sdk.Coins { + stakedCoins := sdk.NewCoins() + k.IterateQueuedStakingsByFarmer(ctx, farmerAcc, func(stakingCoinDenom string, queuedStaking types.QueuedStaking) (stop bool) { + stakedCoins = stakedCoins.Add(sdk.NewCoin(stakingCoinDenom, queuedStaking.Amount)) + return false + }) + return stakedCoins +} + +// GetTotalStakings returns total stakings for given staking coin denom. func (k Keeper) GetTotalStakings(ctx sdk.Context, stakingCoinDenom string) (totalStakings types.TotalStakings, found bool) { store := ctx.KVStore(k.storeKey) bz := store.Get(types.GetTotalStakingsKey(stakingCoinDenom)) @@ -140,17 +163,21 @@ func (k Keeper) GetTotalStakings(ctx sdk.Context, stakingCoinDenom string) (tota return } +// SetTotalStakings sets total stakings for given staking coin denom. func (k Keeper) SetTotalStakings(ctx sdk.Context, stakingCoinDenom string, totalStakings types.TotalStakings) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(&totalStakings) store.Set(types.GetTotalStakingsKey(stakingCoinDenom), bz) } +// DeleteTotalStakings deletes total stakings for given staking coin denom. func (k Keeper) DeleteTotalStakings(ctx sdk.Context, stakingCoinDenom string) { store := ctx.KVStore(k.storeKey) store.Delete(types.GetTotalStakingsKey(stakingCoinDenom)) } +// IncreaseTotalStakings increases total stakings for given staking coin denom +// by given amount. func (k Keeper) IncreaseTotalStakings(ctx sdk.Context, stakingCoinDenom string, amount sdk.Int) { totalStaking, found := k.GetTotalStakings(ctx, stakingCoinDenom) if !found { @@ -160,6 +187,8 @@ func (k Keeper) IncreaseTotalStakings(ctx sdk.Context, stakingCoinDenom string, k.SetTotalStakings(ctx, stakingCoinDenom, totalStaking) } +// DecreaseTotalStakings decreases total stakings for given staking coin denom +// by given amount. func (k Keeper) DecreaseTotalStakings(ctx sdk.Context, stakingCoinDenom string, amount sdk.Int) { totalStaking, found := k.GetTotalStakings(ctx, stakingCoinDenom) if !found { @@ -216,6 +245,7 @@ func (k Keeper) Stake(ctx sdk.Context, farmerAcc sdk.AccAddress, amount sdk.Coin } // Unstake unstakes an amount of staking coins from the staking reserve account. +// It causes accumulated rewards to be withdrawn to the farmer. func (k Keeper) Unstake(ctx sdk.Context, farmerAcc sdk.AccAddress, amount sdk.Coins) error { // TODO: send coins at once, not in every WithdrawRewards @@ -285,6 +315,7 @@ func (k Keeper) Unstake(ctx sdk.Context, farmerAcc sdk.AccAddress, amount sdk.Co } // ProcessQueuedCoins moves queued coins into staked coins. +// It causes accumulated rewards to be withdrawn to the farmer. func (k Keeper) ProcessQueuedCoins(ctx sdk.Context) { k.IterateQueuedStakings(ctx, func(stakingCoinDenom string, farmerAcc sdk.AccAddress, queuedStaking types.QueuedStaking) (stop bool) { staking, found := k.GetStaking(ctx, stakingCoinDenom, farmerAcc) @@ -308,7 +339,9 @@ func (k Keeper) ProcessQueuedCoins(ctx sdk.Context) { }) } -// ValidateStakingReservedAmount checks that the balance of StakingReserveAcc greater than the amount of staked, queued coins in all staking objects. +// ValidateStakingReservedAmount checks that the balance of +// StakingReserveAcc greater than the amount of staked, queued coins in all +// staking objects. func (k Keeper) ValidateStakingReservedAmount(ctx sdk.Context) error { reservedCoins := sdk.NewCoins() k.IterateStakings(ctx, func(stakingCoinDenom string, _ sdk.AccAddress, staking types.Staking) (stop bool) { diff --git a/x/farming/keeper/staking_test.go b/x/farming/keeper/staking_test.go index 63210776..fdd568e7 100644 --- a/x/farming/keeper/staking_test.go +++ b/x/farming/keeper/staking_test.go @@ -127,7 +127,7 @@ func (suite *KeeperTestSuite) TestUnstake() { } else { if suite.NoError(err) { suite.True(coinsEq(tc.remainingStaked, suite.keeper.GetAllStakedCoinsByFarmer(suite.ctx, suite.addrs[tc.addrIdx]))) - suite.True(coinsEq(tc.remainingQueued, suite.keeper.GetAllQueuedStakedCoinsByFarmer(suite.ctx, suite.addrs[tc.addrIdx]))) + suite.True(coinsEq(tc.remainingQueued, suite.keeper.GetAllQueuedCoinsByFarmer(suite.ctx, suite.addrs[tc.addrIdx]))) } } }) @@ -168,14 +168,14 @@ func (suite *KeeperTestSuite) TestProcessQueuedCoins() { } } - suite.Require().True(coinsEq(queuedCoins, suite.keeper.GetAllQueuedStakedCoinsByFarmer(suite.ctx, suite.addrs[0]))) + suite.Require().True(coinsEq(queuedCoins, suite.keeper.GetAllQueuedCoinsByFarmer(suite.ctx, suite.addrs[0]))) suite.Require().True(coinsEq(stakedCoins, suite.keeper.GetAllStakedCoinsByFarmer(suite.ctx, suite.addrs[0]))) suite.keeper.ProcessQueuedCoins(suite.ctx) stakedCoins = stakedCoins.Add(queuedCoins...) queuedCoins = sdk.NewCoins() - suite.Require().True(coinsEq(queuedCoins, suite.keeper.GetAllQueuedStakedCoinsByFarmer(suite.ctx, suite.addrs[0]))) + suite.Require().True(coinsEq(queuedCoins, suite.keeper.GetAllQueuedCoinsByFarmer(suite.ctx, suite.addrs[0]))) suite.Require().True(coinsEq(stakedCoins, suite.keeper.GetAllStakedCoinsByFarmer(suite.ctx, suite.addrs[0]))) } } From 5ffc807b415d623dca28f59bdca9a4cf5bc57a23 Mon Sep 17 00:00:00 2001 From: Hanjun Kim Date: Tue, 12 Oct 2021 14:36:38 +0900 Subject: [PATCH 5/6] chore: add comments for types --- x/farming/types/expected_keepers.go | 1 - x/farming/types/genesis.go | 6 ++++++ x/farming/types/keys.go | 21 ++++++++++++++++++++- x/farming/types/plan.go | 5 +++++ x/farming/types/proposal.go | 15 +++++++++++++++ 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/x/farming/types/expected_keepers.go b/x/farming/types/expected_keepers.go index 5984cb5b..1b3dc2d7 100644 --- a/x/farming/types/expected_keepers.go +++ b/x/farming/types/expected_keepers.go @@ -9,7 +9,6 @@ import ( type BankKeeper interface { SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) error GetAllBalances(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins - //GetBalance(ctx sdk.Context, addr sdk.AccAddress, denom string) sdk.Coin SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins SendCoinsFromModuleToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error diff --git a/x/farming/types/genesis.go b/x/farming/types/genesis.go index f9d75f62..82ab8420 100644 --- a/x/farming/types/genesis.go +++ b/x/farming/types/genesis.go @@ -115,6 +115,7 @@ func ValidateGenesis(data GenesisState) error { return nil } +// Validate validates PlanRecord. func (record PlanRecord) Validate() error { plan, err := UnpackPlan(&record.Plan) if err != nil { @@ -129,6 +130,7 @@ func (record PlanRecord) Validate() error { return nil } +// Validate validates StakingRecord. func (record StakingRecord) Validate() error { if _, err := sdk.AccAddressFromBech32(record.Farmer); err != nil { return err @@ -142,6 +144,7 @@ func (record StakingRecord) Validate() error { return nil } +// Validate validates QueuedStakingRecord. func (record QueuedStakingRecord) Validate() error { if _, err := sdk.AccAddressFromBech32(record.Farmer); err != nil { return err @@ -155,6 +158,7 @@ func (record QueuedStakingRecord) Validate() error { return nil } +// Validate validates HistoricalRewardsRecord. func (record HistoricalRewardsRecord) Validate() error { if err := sdk.ValidateDenom(record.StakingCoinDenom); err != nil { return err @@ -165,6 +169,7 @@ func (record HistoricalRewardsRecord) Validate() error { return nil } +// Validate validates OutstandingRewardsRecord. func (record OutstandingRewardsRecord) Validate() error { if err := sdk.ValidateDenom(record.StakingCoinDenom); err != nil { return err @@ -175,6 +180,7 @@ func (record OutstandingRewardsRecord) Validate() error { return nil } +// Validate validates CurrentEpochRecord. func (record CurrentEpochRecord) Validate() error { if err := sdk.ValidateDenom(record.StakingCoinDenom); err != nil { return err diff --git a/x/farming/types/keys.go b/x/farming/types/keys.go index 56dc0810..8ab0872b 100644 --- a/x/farming/types/keys.go +++ b/x/farming/types/keys.go @@ -50,42 +50,54 @@ func GetStakingKey(stakingCoinDenom string, farmerAcc sdk.AccAddress) []byte { return append(append(StakingKeyPrefix, LengthPrefixString(stakingCoinDenom)...), farmerAcc...) } +// GetStakingIndexKey returns an indexing key for a staking. func GetStakingIndexKey(farmerAcc sdk.AccAddress, stakingCoinDenom string) []byte { return append(append(StakingIndexKeyPrefix, address.MustLengthPrefix(farmerAcc)...), []byte(stakingCoinDenom)...) } +// GetStakingsByFarmerPrefix returns a key prefix used to iterate +// stakings by a farmer. func GetStakingsByFarmerPrefix(farmerAcc sdk.AccAddress) []byte { return append(StakingIndexKeyPrefix, address.MustLengthPrefix(farmerAcc)...) } +// GetQueuedStakingKey returns a key for a queued staking. func GetQueuedStakingKey(stakingCoinDenom string, farmerAcc sdk.AccAddress) []byte { return append(append(QueuedStakingKeyPrefix, LengthPrefixString(stakingCoinDenom)...), farmerAcc...) } +// GetQueuedStakingIndexKey returns an indexing key for a queuded staking. func GetQueuedStakingIndexKey(farmerAcc sdk.AccAddress, stakingCoinDenom string) []byte { return append(append(QueuedStakingIndexKeyPrefix, address.MustLengthPrefix(farmerAcc)...), []byte(stakingCoinDenom)...) } +// GetQueuedStakingByFarmerPrefix returns a key prefix used to iterate +// queued stakings by a farmer. func GetQueuedStakingByFarmerPrefix(farmerAcc sdk.AccAddress) []byte { return append(QueuedStakingIndexKeyPrefix, address.MustLengthPrefix(farmerAcc)...) } +// GetTotalStakingsKey returns a key for a total stakings info. func GetTotalStakingsKey(stakingCoinDenom string) []byte { return append(TotalStakingKeyPrefix, []byte(stakingCoinDenom)...) } +// GetHistoricalRewardsKey returns a key for a historical rewards record. func GetHistoricalRewardsKey(stakingCoinDenom string, epoch uint64) []byte { return append(append(HistoricalRewardsKeyPrefix, LengthPrefixString(stakingCoinDenom)...), sdk.Uint64ToBigEndian(epoch)...) } +// GetCurrentEpochKey returns a key for a current epoch info. func GetCurrentEpochKey(stakingCoinDenom string) []byte { return append(CurrentEpochKeyPrefix, []byte(stakingCoinDenom)...) } +// GetOutstandingRewardsKey returns a key for an outstanding rewards record. func GetOutstandingRewardsKey(stakingCoinDenom string) []byte { return append(OutstandingRewardsKeyPrefix, []byte(stakingCoinDenom)...) } +// ParseStakingKey parses a staking key. func ParseStakingKey(key []byte) (stakingCoinDenom string, farmerAcc sdk.AccAddress) { if !bytes.HasPrefix(key, StakingKeyPrefix) { panic("key does not have proper prefix") @@ -96,6 +108,7 @@ func ParseStakingKey(key []byte) (stakingCoinDenom string, farmerAcc sdk.AccAddr return } +// ParseStakingIndexKey parses a staking index key. func ParseStakingIndexKey(key []byte) (farmerAcc sdk.AccAddress, stakingCoinDenom string) { if !bytes.HasPrefix(key, StakingIndexKeyPrefix) { panic("key does not have proper prefix") @@ -106,6 +119,7 @@ func ParseStakingIndexKey(key []byte) (farmerAcc sdk.AccAddress, stakingCoinDeno return } +// ParseQueuedStakingKey parses a queued staking key. func ParseQueuedStakingKey(key []byte) (stakingCoinDenom string, farmerAcc sdk.AccAddress) { if !bytes.HasPrefix(key, QueuedStakingKeyPrefix) { panic("key does not have proper prefix") @@ -116,6 +130,7 @@ func ParseQueuedStakingKey(key []byte) (stakingCoinDenom string, farmerAcc sdk.A return } +// ParseQueuedStakingIndexKey parses a queued staking index key. func ParseQueuedStakingIndexKey(key []byte) (farmerAcc sdk.AccAddress, stakingCoinDenom string) { if !bytes.HasPrefix(key, QueuedStakingIndexKeyPrefix) { panic("key does not have proper prefix") @@ -126,6 +141,7 @@ func ParseQueuedStakingIndexKey(key []byte) (farmerAcc sdk.AccAddress, stakingCo return } +// ParseHistoricalRewardsKey parses a historical rewards key. func ParseHistoricalRewardsKey(key []byte) (stakingCoinDenom string, epoch uint64) { if !bytes.HasPrefix(key, HistoricalRewardsKeyPrefix) { panic("key does not have proper prefix") @@ -136,6 +152,7 @@ func ParseHistoricalRewardsKey(key []byte) (stakingCoinDenom string, epoch uint6 return } +// ParseCurrentEpochKey parses a current epoch key. func ParseCurrentEpochKey(key []byte) (stakingCoinDenom string) { if !bytes.HasPrefix(key, CurrentEpochKeyPrefix) { panic("key does not have proper prefix") @@ -144,6 +161,7 @@ func ParseCurrentEpochKey(key []byte) (stakingCoinDenom string) { return } +// ParseOutstandingRewardsKey parses an outstanding rewards key. func ParseOutstandingRewardsKey(key []byte) (stakingCoinDenom string) { if !bytes.HasPrefix(key, OutstandingRewardsKeyPrefix) { panic("key does not have proper prefix") @@ -152,7 +170,8 @@ func ParseOutstandingRewardsKey(key []byte) (stakingCoinDenom string) { return } -// LengthPrefixString is LengthPrefix for string. +// LengthPrefixString returns length-prefixed bytes representation +// of a string. func LengthPrefixString(s string) []byte { bz := []byte(s) bzLen := len(bz) diff --git a/x/farming/types/plan.go b/x/farming/types/plan.go index da70d66b..c2e33ab2 100644 --- a/x/farming/types/plan.go +++ b/x/farming/types/plan.go @@ -210,6 +210,7 @@ func (plan BasePlan) MarshalYAML() (interface{}, error) { return string(bz), err } +// NewFixedAmountPlan returns a new fixed amount plan. func NewFixedAmountPlan(basePlan *BasePlan, epochAmount sdk.Coins) *FixedAmountPlan { return &FixedAmountPlan{ BasePlan: basePlan, @@ -217,6 +218,7 @@ func NewFixedAmountPlan(basePlan *BasePlan, epochAmount sdk.Coins) *FixedAmountP } } +// NewRatioPlan returns a new ratio plan. func NewRatioPlan(basePlan *BasePlan, epochRatio sdk.Dec) *RatioPlan { return &RatioPlan{ BasePlan: basePlan, @@ -224,6 +226,7 @@ func NewRatioPlan(basePlan *BasePlan, epochRatio sdk.Dec) *RatioPlan { } } +// PlanI represents a farming plan. type PlanI interface { proto.Message @@ -362,6 +365,8 @@ func IsPlanActiveAt(plan PlanI, t time.Time) bool { return !plan.GetStartTime().After(t) && plan.GetEndTime().After(t) } +// PrivatePlanFarmingPoolAddress returns a unique farming pool address +// for a newly created plan. func PrivatePlanFarmingPoolAddress(name string, planId uint64) sdk.AccAddress { poolAddrName := strings.Join([]string{PrivatePlanFarmingPoolAddrPrefix, fmt.Sprint(planId), name}, PoolAddrSplitter) return address.Module(ModuleName, []byte(poolAddrName)) diff --git a/x/farming/types/proposal.go b/x/farming/types/proposal.go index 2ee89edd..52a5c2bf 100644 --- a/x/farming/types/proposal.go +++ b/x/farming/types/proposal.go @@ -104,14 +104,21 @@ func NewAddRequestProposal( } } +// IsForFixedAmountPlan returns true if the request is for +// fixed amount plan. +// It checks if EpochAmount is not zero. func (p *AddRequestProposal) IsForFixedAmountPlan() bool { return !p.EpochAmount.IsZero() } +// IsForRatioPlan returns true if the request is for +// ratio plan. +// It checks if EpochRatio is not zero. func (p *AddRequestProposal) IsForRatioPlan() bool { return !p.EpochRatio.IsNil() && !p.EpochRatio.IsZero() } +// Validate validates AddRequestProposal. 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) @@ -165,14 +172,21 @@ func NewUpdateRequestProposal( } } +// IsForFixedAmountPlan returns true if the request is for +// fixed amount plan. +// It checks if EpochAmount is not zero. func (p *UpdateRequestProposal) IsForFixedAmountPlan() bool { return !p.EpochAmount.IsZero() } +// IsForRatioPlan returns true if the request is for +// ratio plan. +// It checks if EpochRatio is not zero. func (p *UpdateRequestProposal) IsForRatioPlan() bool { return !p.EpochRatio.IsNil() && !p.EpochRatio.IsZero() } +// Validate validates UpdateRequestProposal. func (p *UpdateRequestProposal) Validate() error { if p.PlanId == 0 { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid plan id: %d", p.PlanId) @@ -213,6 +227,7 @@ func NewDeleteRequestProposal(id uint64) *DeleteRequestProposal { } } +// Validate validates DeleteRequestProposal. func (p *DeleteRequestProposal) Validate() error { if p.PlanId == 0 { return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, "invalid plan id: %d", p.PlanId) From 86d822434eed524aa18d6c1d4c31b461ec4cf6f8 Mon Sep 17 00:00:00 2001 From: Hanjun Kim Date: Thu, 14 Oct 2021 13:37:54 +0900 Subject: [PATCH 6/6] chore: apply changes from code review --- x/farming/keeper/reward.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/farming/keeper/reward.go b/x/farming/keeper/reward.go index cbbe54d6..f584cddb 100644 --- a/x/farming/keeper/reward.go +++ b/x/farming/keeper/reward.go @@ -418,7 +418,6 @@ func (k Keeper) AllocateRewards(ctx sdk.Context) error { // ValidateRemainingRewardsAmount checks that the balance of the // rewards reserve pool is greater than the total amount of // unwithdrawn rewards. -// TODO: correct comment above func (k Keeper) ValidateRemainingRewardsAmount(ctx sdk.Context) error { remainingRewards := sdk.NewCoins() k.IterateStakings(ctx, func(stakingCoinDenom string, farmerAcc sdk.AccAddress, staking types.Staking) (stop bool) {