From 460cb71de3e3b02a69314926bcb8165b663acf10 Mon Sep 17 00:00:00 2001 From: kogisin Date: Mon, 13 Sep 2021 20:55:58 +0900 Subject: [PATCH 01/20] feat: add global keys prefix for the current epoch days --- x/farming/keeper/epoch.go | 25 +++++++++++++++++++++++++ x/farming/types/keys.go | 6 ++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/x/farming/keeper/epoch.go b/x/farming/keeper/epoch.go index 12b46338..f76bd691 100644 --- a/x/farming/keeper/epoch.go +++ b/x/farming/keeper/epoch.go @@ -44,3 +44,28 @@ func (k Keeper) AdvanceEpoch(ctx sdk.Context) error { return nil } + +// GetGlobalCurrentEpochDays returns the global current epoch days. +func (k Keeper) GetGlobalCurrentEpochDays(ctx sdk.Context) uint64 { + var epochDays uint64 + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.GlobalCurrentEpochDaysKey) + if bz == nil { + // initialize the current epoch days + epochDays = 1 + } else { + val := gogotypes.UInt64Value{} + if err := k.cdc.Unmarshal(bz, &val); err != nil { + panic(err) + } + epochDays = val.GetValue() + } + return epochDays +} + +// SetGlobalCurrentEpochDays sets the global current epoch days. +func (k Keeper) SetGlobalCurrentEpochDays(ctx sdk.Context, epochDays uint64) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshal(&gogotypes.UInt64Value{Value: epochDays}) + store.Set(types.GlobalCurrentEpochDaysKey, bz) +} diff --git a/x/farming/types/keys.go b/x/farming/types/keys.go index 206f9187..546cc2b7 100644 --- a/x/farming/types/keys.go +++ b/x/farming/types/keys.go @@ -21,9 +21,11 @@ const ( QuerierRoute = ModuleName ) +// keys for farming store prefixes var ( - GlobalPlanIdKey = []byte("globalPlanId") - GlobalLastEpochTimeKey = []byte("globalLastEpochTime") + GlobalPlanIdKey = []byte("globalPlanId") + GlobalLastEpochTimeKey = []byte("globalLastEpochTime") + GlobalCurrentEpochDaysKey = []byte("globalCurrentEpochDays") PlanKeyPrefix = []byte{0x11} PlansByFarmerIndexKeyPrefix = []byte{0x12} From ac493572484db03911f9314c07ac8dd725c98d52 Mon Sep 17 00:00:00 2001 From: kogisin Date: Mon, 13 Sep 2021 20:56:19 +0900 Subject: [PATCH 02/20] test: add test for key store prefixes --- x/farming/types/keys_test.go | 263 +++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 x/farming/types/keys_test.go diff --git a/x/farming/types/keys_test.go b/x/farming/types/keys_test.go new file mode 100644 index 00000000..456c40a6 --- /dev/null +++ b/x/farming/types/keys_test.go @@ -0,0 +1,263 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/suite" + + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/tendermint/farming/x/farming/types" +) + +type keysTestSuite struct { + suite.Suite +} + +func TestKeysTestSuite(t *testing.T) { + suite.Run(t, new(keysTestSuite)) +} + +func (s *keysTestSuite) TestGetPlanKey() { + s.Require().Equal([]byte{0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa}, types.GetPlanKey(10)) + s.Require().Equal([]byte{0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9}, types.GetPlanKey(9)) + s.Require().Equal([]byte{0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, types.GetPlanKey(0)) +} + +func (s *keysTestSuite) TestGetPlansByFarmerIndexKey() { + s.Require().Equal([]byte{0x12}, types.GetPlansByFarmerIndexKey(sdk.AccAddress(""))) + s.Require().Equal([]byte{0x12, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31}, types.GetPlansByFarmerIndexKey(sdk.AccAddress("farmer1"))) + s.Require().Equal([]byte{0x12, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32}, types.GetPlansByFarmerIndexKey(sdk.AccAddress("farmer2"))) + s.Require().Equal([]byte{0x12, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33}, types.GetPlansByFarmerIndexKey(sdk.AccAddress("farmer3"))) +} + +func (s *keysTestSuite) TestGetPlanByFarmerAddrIndexKey() { + testCases := []struct { + farmerAcc sdk.AccAddress + planID uint64 + expected []byte + }{ + { + nil, + 1, + []byte{0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, + }, + { + sdk.AccAddress("farmer1"), + 1, + []byte{0x12, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, + }, + { + sdk.AccAddress("farmer2"), + 2, + []byte{0x12, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, + }, + { + sdk.AccAddress("farmer3"), + 2, + []byte{0x12, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, + }, + } + + for _, tc := range testCases { + s.Require().Equal(tc.expected, types.GetPlanByFarmerAddrIndexKey(tc.farmerAcc, tc.planID)) + } +} + +func (s *keysTestSuite) TestGetStakingKey() { + testCases := []struct { + stakingCoinDenom string + farmerAcc sdk.AccAddress + expected []byte + }{ + // TODO: see the first case of TestGetStakingIndexKey + { + sdk.DefaultBondDenom, + sdk.AccAddress(""), + []byte{0x21, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65}, + }, + { + sdk.DefaultBondDenom, + sdk.AccAddress("farmer1"), + []byte{0x21, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31}, + }, + { + sdk.DefaultBondDenom, + sdk.AccAddress("farmer2"), + []byte{0x21, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32}, + }, + { + sdk.DefaultBondDenom, + sdk.AccAddress("farmer3"), + []byte{0x21, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33}, + }, + } + + for _, tc := range testCases { + key := types.GetStakingKey(tc.stakingCoinDenom, tc.farmerAcc) + s.Require().Equal(tc.expected, key) + + stakingCoinDenom, farmerAcc := types.ParseStakingKey(key) + s.Require().Equal(tc.stakingCoinDenom, stakingCoinDenom) + s.Require().Equal(tc.farmerAcc, farmerAcc) + } +} + +func (s *keysTestSuite) TestGetStakingIndexKey() { + testCases := []struct { + farmerAcc sdk.AccAddress + stakingCoinDenom string + expected []byte + }{ + // TODO: should we cover only happy cases? below case returns panic since farmerAcc is empty + // How about the case1 for TestGetStakingKey()? It allows empty farmerAcc. + // { + // sdk.AccAddress(""), + // sdk.DefaultBondDenom, + // []byte{0x22, 0x73, 0x74, 0x61, 0x6b, 0x65}, + // }, + { + sdk.AccAddress("farmer1"), + sdk.DefaultBondDenom, + []byte{0x22, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31, 0x73, 0x74, 0x61, 0x6b, 0x65}, + }, + { + sdk.AccAddress("farmer2"), + sdk.DefaultBondDenom, + []byte{0x22, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32, 0x73, 0x74, 0x61, 0x6b, 0x65}, + }, + { + sdk.AccAddress("farmer3"), + sdk.DefaultBondDenom, + []byte{0x22, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33, 0x73, 0x74, 0x61, 0x6b, 0x65}, + }, + } + + for _, tc := range testCases { + key := types.GetStakingIndexKey(tc.farmerAcc, tc.stakingCoinDenom) + s.Require().Equal(tc.expected, key) + + stakingCoinDenom, farmerAcc := types.ParseStakingIndexKey(key) + s.Require().Equal(tc.stakingCoinDenom, stakingCoinDenom) + s.Require().Equal(tc.farmerAcc, farmerAcc) + } +} + +func (s *keysTestSuite) TestGetStakingsByFarmerPrefix() { + s.Require().Equal([]byte{0x22}, types.GetStakingsByFarmerPrefix(sdk.AccAddress(""))) + s.Require().Equal([]byte{0x22, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31}, types.GetStakingsByFarmerPrefix(sdk.AccAddress("farmer1"))) + s.Require().Equal([]byte{0x22, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32}, types.GetStakingsByFarmerPrefix(sdk.AccAddress("farmer2"))) + s.Require().Equal([]byte{0x22, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33}, types.GetStakingsByFarmerPrefix(sdk.AccAddress("farmer3"))) +} + +func (s *keysTestSuite) TestGetQueuedStakingKey() { + testCases := []struct { + stakingCoinDenom string + farmerAcc sdk.AccAddress + expected []byte + }{ + { + sdk.DefaultBondDenom, + nil, + []byte{0x23, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65}, + }, + { + sdk.DefaultBondDenom, + sdk.AccAddress("farmer1"), + []byte{0x23, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31}, + }, + { + sdk.DefaultBondDenom, + sdk.AccAddress("farmer2"), + []byte{0x23, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32}, + }, + { + sdk.DefaultBondDenom, + sdk.AccAddress("farmer3"), + []byte{0x23, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33}, + }, + } + + for _, tc := range testCases { + s.Require().Equal(tc.expected, types.GetQueuedStakingKey(tc.stakingCoinDenom, tc.farmerAcc)) + } +} + +func (s *keysTestSuite) TestGetQueuedStakingIndexKey() { + testCases := []struct { + farmerAcc sdk.AccAddress + stakingCoinDenom string + expected []byte + }{ + { + sdk.AccAddress(""), + sdk.DefaultBondDenom, + []byte{0x24, 0x73, 0x74, 0x61, 0x6b, 0x65}, + }, + { + sdk.AccAddress("farmer1"), + sdk.DefaultBondDenom, + []byte{0x24, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31, 0x73, 0x74, 0x61, 0x6b, 0x65}, + }, + { + sdk.AccAddress("farmer2"), + sdk.DefaultBondDenom, + []byte{0x24, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32, 0x73, 0x74, 0x61, 0x6b, 0x65}, + }, + { + sdk.AccAddress("farmer3"), + sdk.DefaultBondDenom, + []byte{0x24, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33, 0x73, 0x74, 0x61, 0x6b, 0x65}, + }, + } + + for _, tc := range testCases { + key := types.GetQueuedStakingIndexKey(tc.farmerAcc, tc.stakingCoinDenom) + s.Require().Equal(tc.expected, key) + } +} + +func (s *keysTestSuite) TestGetQueuedStakingByFarmerPrefix() { + s.Require().Equal([]byte{0x24}, types.GetQueuedStakingByFarmerPrefix(sdk.AccAddress(""))) + s.Require().Equal([]byte{0x24, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31}, types.GetQueuedStakingByFarmerPrefix(sdk.AccAddress("farmer1"))) + s.Require().Equal([]byte{0x24, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32}, types.GetQueuedStakingByFarmerPrefix(sdk.AccAddress("farmer2"))) + s.Require().Equal([]byte{0x24, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33}, types.GetQueuedStakingByFarmerPrefix(sdk.AccAddress("farmer3"))) +} + +func (s *keysTestSuite) TestGetTotalStakingKey() { + s.Require().Equal([]byte{0x25}, types.GetTotalStakingKey("")) + s.Require().Equal([]byte{0x25, 0x73, 0x74, 0x61, 0x6b, 0x65}, types.GetTotalStakingKey(sdk.DefaultBondDenom)) +} + +func (s *keysTestSuite) TestGetHistoricalRewardsKey() { + testCases := []struct { + stakingCoinDenom string + epoch uint64 + expected []byte + }{ + { + "", + 0, + []byte{0x31, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + }, + { + sdk.DefaultBondDenom, + 1, + []byte{0x31, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, + }, + { + sdk.DefaultBondDenom, + 2, + []byte{0x31, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, + }, + } + + for _, tc := range testCases { + s.Require().Equal(tc.expected, types.GetHistoricalRewardsKey(tc.stakingCoinDenom, tc.epoch)) + } +} + +func (s *keysTestSuite) TestGetCurrentEpochKey() { + s.Require().Equal([]byte{0x32}, types.GetCurrentEpochKey("")) + s.Require().Equal([]byte{0x32, 0x73, 0x74, 0x61, 0x6b, 0x65}, types.GetCurrentEpochKey(sdk.DefaultBondDenom)) +} From d25affb46b740d5f5cc9557ee65be32e40452a05 Mon Sep 17 00:00:00 2001 From: kogisin Date: Mon, 13 Sep 2021 21:36:48 +0900 Subject: [PATCH 03/20] chore: fix broken store prefix test, rename EpochDays to NextEpochDays --- .../tendermint/farming/v1beta1/farming.proto | 4 +- x/farming/abci.go | 2 +- x/farming/keeper/epoch_test.go | 4 +- x/farming/types/farming.pb.go | 160 +++++++++--------- x/farming/types/genesis_test.go | 4 +- x/farming/types/keys_test.go | 4 +- x/farming/types/params.go | 10 +- x/farming/types/params_test.go | 4 +- 8 files changed, 96 insertions(+), 96 deletions(-) diff --git a/proto/tendermint/farming/v1beta1/farming.proto b/proto/tendermint/farming/v1beta1/farming.proto index 81d861c0..9da143e7 100644 --- a/proto/tendermint/farming/v1beta1/farming.proto +++ b/proto/tendermint/farming/v1beta1/farming.proto @@ -23,8 +23,8 @@ message Params { ]; // The universal epoch length in number of days. Every process for staking and - // reward distribution is executed with this epoch_days frequency - uint32 epoch_days = 2 [(gogoproto.moretags) = "yaml:\"epoch_days\""]; + // reward distribution is executed with this next_epoch_days frequency + uint32 next_epoch_days = 2 [(gogoproto.moretags) = "yaml:\"next_epoch_days\""]; // farming_fee_collector is the module account address to collect fees within the farming module string farming_fee_collector = 3 [(gogoproto.moretags) = "yaml:\"farming_fee_collector\""]; diff --git a/x/farming/abci.go b/x/farming/abci.go index f67497df..f12ad5a5 100644 --- a/x/farming/abci.go +++ b/x/farming/abci.go @@ -27,7 +27,7 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) { if !found { k.SetLastEpochTime(ctx, ctx.BlockTime()) } else { - y, m, d := lastEpochTime.AddDate(0, 0, int(params.EpochDays)).Date() + y, m, d := lastEpochTime.AddDate(0, 0, int(params.NextEpochDays)).Date() y2, m2, d2 := ctx.BlockTime().Date() if y == y2 && m == m2 && d == d2 { if err := k.AdvanceEpoch(ctx); err != nil { diff --git a/x/farming/keeper/epoch_test.go b/x/farming/keeper/epoch_test.go index 11ae4ca8..7bc2e2b0 100644 --- a/x/farming/keeper/epoch_test.go +++ b/x/farming/keeper/epoch_test.go @@ -26,7 +26,7 @@ func (suite *KeeperTestSuite) TestFirstEpoch() { // than epoch_days parameter on the first epoch. params := suite.keeper.GetParams(suite.ctx) - suite.Require().Equal(uint32(1), params.EpochDays) + suite.Require().Equal(uint32(1), params.NextEpochDays) suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-08-11T23:59:59Z")) farming.EndBlocker(suite.ctx, suite.keeper) @@ -45,7 +45,7 @@ func (suite *KeeperTestSuite) TestEpochDays() { suite.SetupTest() params := suite.keeper.GetParams(suite.ctx) - params.EpochDays = epochDays + params.NextEpochDays = epochDays suite.keeper.SetParams(suite.ctx, params) t := mustParseRFC3339("2021-08-11T00:00:00Z") diff --git a/x/farming/types/farming.pb.go b/x/farming/types/farming.pb.go index 573f9f39..0b588af1 100644 --- a/x/farming/types/farming.pb.go +++ b/x/farming/types/farming.pb.go @@ -68,8 +68,8 @@ type Params struct { // this fee prevents from spamming and it is collected in the community pool PrivatePlanCreationFee github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=private_plan_creation_fee,json=privatePlanCreationFee,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"private_plan_creation_fee" yaml:"private_plan_creation_fee"` // The universal epoch length in number of days. Every process for staking and - // reward distribution is executed with this epoch_days frequency - EpochDays uint32 `protobuf:"varint,2,opt,name=epoch_days,json=epochDays,proto3" json:"epoch_days,omitempty" yaml:"epoch_days"` + // reward distribution is executed with this next_epoch_days frequency + NextEpochDays uint32 `protobuf:"varint,2,opt,name=next_epoch_days,json=nextEpochDays,proto3" json:"next_epoch_days,omitempty" yaml:"next_epoch_days"` // farming_fee_collector is the module account address to collect fees within the farming module FarmingFeeCollector string `protobuf:"bytes,3,opt,name=farming_fee_collector,json=farmingFeeCollector,proto3" json:"farming_fee_collector,omitempty" yaml:"farming_fee_collector"` } @@ -417,77 +417,77 @@ func init() { } var fileDescriptor_5b657e0809d9de86 = []byte{ - // 1114 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0x4f, 0x6f, 0x1b, 0x45, - 0x14, 0xf7, 0xb8, 0x6e, 0x62, 0x8f, 0x9b, 0xc4, 0x9e, 0xfc, 0x61, 0xe3, 0xb6, 0xde, 0xd5, 0x4a, - 0x20, 0x2b, 0x28, 0xb6, 0x1a, 0x7a, 0xca, 0x89, 0x38, 0x7f, 0x8a, 0xa5, 0x28, 0xb8, 0x5b, 0x87, - 0x02, 0x02, 0xad, 0xc6, 0xde, 0x89, 0xb3, 0xea, 0x7a, 0xc7, 0xda, 0x19, 0x27, 0xcd, 0x07, 0x40, - 0xaa, 0x72, 0xaa, 0x10, 0x07, 0x2e, 0x41, 0x15, 0xdc, 0xca, 0x95, 0xef, 0x40, 0x25, 0x2e, 0x11, - 0x12, 0x12, 0xe2, 0xb0, 0x45, 0xc9, 0x37, 0xf0, 0x99, 0x03, 0xda, 0x99, 0x59, 0x67, 0x11, 0x0e, - 0x69, 0x24, 0x7a, 0xf2, 0xce, 0x9b, 0xf7, 0x7e, 0xef, 0xf7, 0xde, 0xbe, 0xdf, 0xf3, 0xc2, 0x0a, - 0x27, 0xbe, 0x43, 0x82, 0x9e, 0xeb, 0xf3, 0xda, 0x1e, 0x8e, 0x7e, 0xbb, 0xb5, 0x83, 0x7b, 0x6d, - 0xc2, 0xf1, 0xbd, 0xf8, 0x5c, 0xed, 0x07, 0x94, 0x53, 0xb4, 0xd0, 0xa1, 0xac, 0x47, 0x59, 0x35, - 0xb6, 0x2a, 0xaf, 0xd2, 0x5c, 0x97, 0x76, 0xa9, 0x70, 0xa9, 0x45, 0x4f, 0xd2, 0xbb, 0xb4, 0x28, - 0xbd, 0x6d, 0x79, 0xa1, 0x42, 0xe5, 0x55, 0x59, 0x9e, 0x6a, 0x6d, 0xcc, 0xc8, 0x28, 0x57, 0x87, - 0xba, 0xbe, 0xba, 0xd7, 0xbb, 0x94, 0x76, 0x3d, 0x52, 0x13, 0xa7, 0xf6, 0x60, 0xaf, 0xc6, 0xdd, - 0x1e, 0x61, 0x1c, 0xf7, 0xfa, 0xd2, 0xc1, 0xfc, 0x25, 0x0d, 0x27, 0x9a, 0x38, 0xc0, 0x3d, 0x86, - 0x5e, 0x02, 0xb8, 0xd8, 0x0f, 0xdc, 0x03, 0xcc, 0x89, 0xdd, 0xf7, 0xb0, 0x6f, 0x77, 0x02, 0x82, - 0xb9, 0x4b, 0x7d, 0x7b, 0x8f, 0x10, 0x0d, 0x18, 0x37, 0x2a, 0xf9, 0x95, 0xc5, 0xaa, 0x4a, 0x1f, - 0x25, 0x8c, 0x69, 0x57, 0xd7, 0xa9, 0xeb, 0xd7, 0x5b, 0xaf, 0x42, 0x3d, 0x35, 0x0c, 0x75, 0xe3, - 0x08, 0xf7, 0xbc, 0x55, 0xf3, 0x52, 0x24, 0xf3, 0xe5, 0x6b, 0xbd, 0xd2, 0x75, 0xf9, 0xfe, 0xa0, - 0x5d, 0xed, 0xd0, 0x9e, 0xaa, 0x47, 0xfd, 0x2c, 0x33, 0xe7, 0x49, 0x8d, 0x1f, 0xf5, 0x09, 0x13, - 0xa0, 0xcc, 0x5a, 0x50, 0x38, 0x4d, 0x0f, 0xfb, 0xeb, 0x0a, 0x65, 0x8b, 0x10, 0x74, 0x1f, 0x42, - 0xd2, 0xa7, 0x9d, 0x7d, 0xdb, 0xc1, 0x47, 0x4c, 0x4b, 0x1b, 0xa0, 0x32, 0x55, 0x9f, 0x1f, 0x86, - 0x7a, 0x51, 0x66, 0xbf, 0xb8, 0x33, 0xad, 0x9c, 0x38, 0x6c, 0xe0, 0x23, 0x86, 0x5a, 0x70, 0x5e, - 0xb5, 0x3c, 0x62, 0x62, 0x77, 0xa8, 0xe7, 0x91, 0x0e, 0xa7, 0x81, 0x76, 0xc3, 0x00, 0x95, 0x5c, - 0xdd, 0x18, 0x86, 0xfa, 0x1d, 0x09, 0x30, 0xd6, 0xcd, 0xb4, 0x66, 0x95, 0x7d, 0x8b, 0x90, 0xf5, - 0xd8, 0xba, 0x9a, 0x7d, 0xf6, 0x42, 0x4f, 0x7d, 0xfb, 0x42, 0x4f, 0x99, 0xdf, 0x4d, 0xc2, 0x6c, - 0x1d, 0x33, 0xc1, 0x16, 0x4d, 0xc3, 0xb4, 0xeb, 0x68, 0xc0, 0x00, 0x95, 0x8c, 0x95, 0x76, 0x1d, - 0x84, 0x60, 0xc6, 0xc7, 0x3d, 0x22, 0xc8, 0xe6, 0x2c, 0xf1, 0x8c, 0xee, 0xc3, 0x4c, 0x54, 0xad, - 0xc8, 0x3f, 0xbd, 0x62, 0x54, 0xc7, 0xcf, 0x45, 0x35, 0xc2, 0x6b, 0x1d, 0xf5, 0x89, 0x25, 0xbc, - 0xd1, 0x43, 0x38, 0x17, 0xf3, 0xeb, 0x53, 0xea, 0xd9, 0xd8, 0x71, 0x02, 0xc2, 0x98, 0x96, 0x11, - 0x55, 0xe8, 0xc3, 0x50, 0xbf, 0xfd, 0xcf, 0x2a, 0x92, 0x5e, 0xa6, 0x85, 0x94, 0xb9, 0x49, 0xa9, - 0xb7, 0x26, 0x8d, 0xe8, 0x63, 0x38, 0xcb, 0xc5, 0xe8, 0xca, 0xf7, 0x14, 0x23, 0xde, 0x14, 0x88, - 0xe5, 0x61, 0xa8, 0x97, 0x24, 0xe2, 0x18, 0x27, 0xd3, 0x42, 0x09, 0x6b, 0x0c, 0xf8, 0x3d, 0x80, - 0x73, 0x8c, 0xe3, 0x27, 0x51, 0xfa, 0x68, 0x20, 0xed, 0x43, 0xe2, 0x76, 0xf7, 0x39, 0xd3, 0x26, - 0xc4, 0x20, 0xdd, 0x19, 0x3b, 0x48, 0x1b, 0xa4, 0x23, 0x66, 0xc9, 0x52, 0xb3, 0xa4, 0xca, 0x18, - 0x87, 0x13, 0x8d, 0xd1, 0xfb, 0x6f, 0x30, 0x46, 0x0a, 0x92, 0x59, 0x48, 0xa1, 0x44, 0xa7, 0xc7, - 0x12, 0x03, 0x7d, 0x0a, 0x21, 0xe3, 0x38, 0xe0, 0x76, 0x24, 0x0b, 0x6d, 0xd2, 0x00, 0x95, 0xfc, - 0x4a, 0xa9, 0x2a, 0x35, 0x53, 0x8d, 0x35, 0x53, 0x6d, 0xc5, 0x9a, 0xa9, 0xdf, 0x55, 0xbc, 0x8a, - 0x23, 0x5e, 0x2a, 0xd6, 0x7c, 0xfe, 0x5a, 0x07, 0x56, 0x4e, 0x18, 0x22, 0x77, 0x64, 0xc1, 0x2c, - 0xf1, 0x1d, 0x89, 0x9b, 0xbd, 0x12, 0xf7, 0xb6, 0xc2, 0x9d, 0x51, 0xd3, 0xab, 0x22, 0x25, 0xea, - 0x24, 0xf1, 0x1d, 0x81, 0x59, 0x86, 0x30, 0x6e, 0x34, 0x71, 0xb4, 0x9c, 0x01, 0x2a, 0x59, 0x2b, - 0x61, 0x41, 0x87, 0x70, 0xc1, 0xc3, 0x8c, 0xdb, 0x8e, 0xcb, 0x78, 0xe0, 0xb6, 0x07, 0xe2, 0x25, - 0x09, 0x06, 0xf0, 0x4a, 0x06, 0xef, 0x0e, 0x43, 0xfd, 0xae, 0xcc, 0x3e, 0x1e, 0x43, 0x72, 0x99, - 0x8b, 0x2e, 0x37, 0x12, 0x77, 0x82, 0xd8, 0x37, 0x00, 0x16, 0x47, 0x01, 0xc4, 0x11, 0xef, 0x89, - 0x69, 0xf9, 0xab, 0x36, 0xc6, 0xb6, 0xaa, 0x5a, 0x93, 0x79, 0xff, 0x85, 0x70, 0xbd, 0x4d, 0x51, - 0x48, 0xc4, 0x0b, 0xcb, 0x6a, 0x31, 0xd6, 0xe5, 0xaf, 0x3f, 0x2d, 0xdf, 0x8c, 0x24, 0xd4, 0x30, - 0xff, 0x02, 0x70, 0x66, 0xcb, 0x7d, 0x4a, 0x9c, 0xb5, 0x1e, 0x1d, 0xf8, 0x5c, 0xe8, 0xf4, 0x31, - 0xcc, 0x45, 0xdc, 0xc4, 0xa6, 0x12, 0x72, 0xcd, 0x5f, 0x2e, 0xc4, 0x58, 0xdc, 0x75, 0xed, 0x34, - 0xd4, 0xc1, 0x30, 0xd4, 0x0b, 0x92, 0xfb, 0x08, 0xc0, 0xb4, 0xb2, 0xed, 0x78, 0x01, 0x7c, 0x05, - 0xe0, 0x2d, 0xb9, 0x88, 0xb0, 0xc8, 0xa6, 0xa5, 0xaf, 0xea, 0xc8, 0x03, 0xd5, 0x91, 0xd9, 0xe4, - 0x16, 0x93, 0xc1, 0xd7, 0x6b, 0x46, 0x5e, 0x84, 0xca, 0x22, 0x13, 0xfb, 0xe9, 0x37, 0x00, 0x73, - 0x56, 0x24, 0xd3, 0xb7, 0x5b, 0x38, 0x81, 0x32, 0xbf, 0x1d, 0x44, 0xb9, 0xe4, 0xc2, 0xab, 0x6f, - 0x44, 0xb5, 0xfd, 0x11, 0xea, 0xef, 0xbd, 0x99, 0x68, 0x87, 0xa1, 0x8e, 0x92, 0x5d, 0x10, 0x50, - 0xa6, 0x25, 0xb7, 0xbe, 0xa8, 0x21, 0x51, 0xd7, 0x09, 0x80, 0x93, 0x8f, 0xa4, 0xbc, 0xd1, 0x16, - 0x9c, 0x50, 0xed, 0x06, 0x22, 0x6f, 0xf5, 0x1a, 0x79, 0x1b, 0x3e, 0xb7, 0x54, 0x34, 0xfa, 0x10, - 0x4e, 0x0b, 0x39, 0x47, 0x8b, 0x47, 0x24, 0x15, 0x75, 0x64, 0xea, 0x8b, 0xc3, 0x50, 0x9f, 0x4f, - 0xe8, 0x7f, 0x74, 0x6f, 0x5a, 0x53, 0xb1, 0x61, 0x33, 0x3a, 0x27, 0xf8, 0x7d, 0x09, 0xa7, 0x1e, - 0x0e, 0xc8, 0x80, 0x38, 0xff, 0x33, 0xc9, 0xd5, 0x4c, 0x94, 0xc2, 0xfc, 0x02, 0xde, 0x6a, 0x51, - 0x8e, 0xbd, 0xb7, 0x83, 0xfe, 0x33, 0x80, 0xc5, 0x8f, 0x5c, 0xc6, 0x69, 0xe0, 0x76, 0xb0, 0x67, - 0x91, 0x43, 0x1c, 0x38, 0x0c, 0xfd, 0x08, 0xe0, 0x3b, 0x9d, 0x41, 0x6f, 0xe0, 0x61, 0xee, 0x1e, - 0x10, 0x7b, 0xe0, 0xbb, 0xdc, 0x0e, 0xe4, 0x9d, 0xfa, 0x56, 0xf8, 0xef, 0x15, 0xbf, 0xab, 0x46, - 0xbd, 0x2c, 0x5b, 0x79, 0x09, 0xd4, 0xb5, 0xb7, 0xfc, 0xfc, 0x05, 0xd0, 0xae, 0xef, 0x72, 0xc5, - 0x56, 0x56, 0xb2, 0xf4, 0x35, 0x80, 0xd9, 0xf8, 0xaf, 0x14, 0x2d, 0xc1, 0xf9, 0xe6, 0xf6, 0xda, - 0x8e, 0xdd, 0xfa, 0xac, 0xb9, 0x69, 0xef, 0xee, 0x3c, 0x6a, 0x6e, 0xae, 0x37, 0xb6, 0x1a, 0x9b, - 0x1b, 0x85, 0x54, 0x69, 0xe6, 0xf8, 0xc4, 0xc8, 0xc7, 0x8e, 0x3b, 0xae, 0x87, 0x2a, 0xb0, 0x70, - 0xe1, 0xdb, 0xdc, 0xad, 0x6f, 0x37, 0xd6, 0x0b, 0xa0, 0x84, 0x8e, 0x4f, 0x8c, 0xe9, 0xd8, 0xad, - 0x39, 0x68, 0x7b, 0x6e, 0x07, 0x2d, 0xc1, 0x62, 0xc2, 0xd3, 0x6a, 0x7c, 0xb2, 0xd6, 0xda, 0x2c, - 0xa4, 0x4b, 0xb3, 0xc7, 0x27, 0xc6, 0xcc, 0xc8, 0x55, 0x7e, 0xd2, 0x94, 0x32, 0xcf, 0x7e, 0x28, - 0xa7, 0xea, 0x0f, 0x5e, 0x9d, 0x95, 0xc1, 0xe9, 0x59, 0x19, 0xfc, 0x79, 0x56, 0x06, 0xcf, 0xcf, - 0xcb, 0xa9, 0xd3, 0xf3, 0x72, 0xea, 0xf7, 0xf3, 0x72, 0xea, 0xf3, 0xe5, 0x44, 0xe1, 0x63, 0x3e, - 0x2d, 0x9f, 0x8e, 0x9e, 0x44, 0x0f, 0xda, 0x13, 0x62, 0xad, 0x7f, 0xf0, 0x77, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xf2, 0x14, 0x99, 0x82, 0x87, 0x0a, 0x00, 0x00, + // 1119 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xcd, 0x6f, 0x1b, 0x45, + 0x14, 0xf7, 0xb8, 0x6e, 0x62, 0x8f, 0x9b, 0xc4, 0x99, 0x7c, 0xb0, 0x71, 0x5b, 0xef, 0x6a, 0x25, + 0x90, 0x55, 0x54, 0x5b, 0x0d, 0x9c, 0x72, 0x22, 0xce, 0x47, 0xb1, 0x14, 0x05, 0x77, 0xeb, 0x50, + 0x40, 0xa0, 0xd5, 0x78, 0x77, 0xe2, 0xac, 0xba, 0xde, 0xb5, 0x76, 0xc6, 0xf9, 0xf8, 0x03, 0x90, + 0xaa, 0x9c, 0x2a, 0xc4, 0x81, 0x4b, 0x50, 0x05, 0xb7, 0x72, 0xe5, 0x7f, 0xa0, 0xc7, 0x08, 0x09, + 0x09, 0x38, 0x6c, 0x51, 0xf2, 0x1f, 0xf8, 0xcc, 0x01, 0xcd, 0xc7, 0xba, 0x0b, 0x38, 0xa4, 0x91, + 0xe8, 0xc9, 0x3b, 0x6f, 0x7e, 0xef, 0xf7, 0x7e, 0xef, 0xed, 0x7b, 0xcf, 0x0b, 0xab, 0x8c, 0x04, + 0x2e, 0x89, 0x7a, 0x5e, 0xc0, 0xea, 0xbb, 0x98, 0xff, 0x76, 0xeb, 0xfb, 0xf7, 0x3a, 0x84, 0xe1, + 0x7b, 0xc9, 0xb9, 0xd6, 0x8f, 0x42, 0x16, 0xa2, 0x45, 0x27, 0xa4, 0xbd, 0x90, 0xd6, 0x12, 0xab, + 0x42, 0x95, 0xe7, 0xbb, 0x61, 0x37, 0x14, 0x90, 0x3a, 0x7f, 0x92, 0xe8, 0xf2, 0x92, 0x44, 0xdb, + 0xf2, 0x42, 0xb9, 0xca, 0xab, 0x8a, 0x3c, 0xd5, 0x3b, 0x98, 0x92, 0x51, 0x2c, 0x27, 0xf4, 0x02, + 0x75, 0xaf, 0x77, 0xc3, 0xb0, 0xeb, 0x93, 0xba, 0x38, 0x75, 0x06, 0xbb, 0x75, 0xe6, 0xf5, 0x08, + 0x65, 0xb8, 0xd7, 0x97, 0x00, 0xf3, 0xb7, 0x2c, 0x9c, 0x68, 0xe1, 0x08, 0xf7, 0x28, 0x7a, 0x0e, + 0xe0, 0x52, 0x3f, 0xf2, 0xf6, 0x31, 0x23, 0x76, 0xdf, 0xc7, 0x81, 0xed, 0x44, 0x04, 0x33, 0x2f, + 0x0c, 0xec, 0x5d, 0x42, 0x34, 0x60, 0x5c, 0xab, 0x16, 0x97, 0x97, 0x6a, 0x2a, 0x3c, 0x0f, 0x98, + 0xc8, 0xae, 0xad, 0x85, 0x5e, 0xd0, 0x68, 0xbf, 0x88, 0xf5, 0xcc, 0x30, 0xd6, 0x8d, 0x23, 0xdc, + 0xf3, 0x57, 0xcc, 0x0b, 0x99, 0xcc, 0xe7, 0x2f, 0xf5, 0x6a, 0xd7, 0x63, 0x7b, 0x83, 0x4e, 0xcd, + 0x09, 0x7b, 0x2a, 0x1f, 0xf5, 0x73, 0x97, 0xba, 0x8f, 0xeb, 0xec, 0xa8, 0x4f, 0xa8, 0x20, 0xa5, + 0xd6, 0xa2, 0xe2, 0x69, 0xf9, 0x38, 0x58, 0x53, 0x2c, 0x9b, 0x84, 0xa0, 0x06, 0x9c, 0x09, 0xc8, + 0x21, 0xb3, 0x49, 0x3f, 0x74, 0xf6, 0x6c, 0x17, 0x1f, 0x51, 0x2d, 0x6b, 0x80, 0xea, 0x54, 0xa3, + 0x3c, 0x8c, 0xf5, 0x45, 0x29, 0xe1, 0x1f, 0x00, 0xd3, 0x9a, 0xe2, 0x96, 0x0d, 0x6e, 0x58, 0xc7, + 0x47, 0x14, 0xb5, 0xe1, 0x82, 0x7a, 0x01, 0x5c, 0x97, 0xed, 0x84, 0xbe, 0x4f, 0x1c, 0x16, 0x46, + 0xda, 0x35, 0x03, 0x54, 0x0b, 0x0d, 0x63, 0x18, 0xeb, 0xb7, 0x24, 0xd3, 0x58, 0x98, 0x69, 0xcd, + 0x29, 0xfb, 0x26, 0x21, 0x6b, 0x89, 0x75, 0x25, 0xff, 0xe4, 0x99, 0x9e, 0xf9, 0xe6, 0x99, 0x9e, + 0x31, 0xbf, 0x9d, 0x84, 0xf9, 0x06, 0xa6, 0x42, 0x3b, 0x9a, 0x86, 0x59, 0xcf, 0xd5, 0x80, 0x01, + 0xaa, 0x39, 0x2b, 0xeb, 0xb9, 0x08, 0xc1, 0x5c, 0x80, 0x7b, 0x44, 0xa8, 0x2e, 0x58, 0xe2, 0x19, + 0xbd, 0x0f, 0x73, 0x3c, 0x77, 0x11, 0x7f, 0x7a, 0xd9, 0xa8, 0x8d, 0xef, 0x92, 0x1a, 0xe7, 0x6b, + 0x1f, 0xf5, 0x89, 0x25, 0xd0, 0xe8, 0x01, 0x9c, 0x4f, 0xf4, 0xf5, 0xc3, 0xd0, 0xb7, 0xb1, 0xeb, + 0x46, 0x84, 0x52, 0x2d, 0x27, 0xb2, 0xd0, 0x87, 0xb1, 0x7e, 0xf3, 0xef, 0x59, 0xa4, 0x51, 0xa6, + 0x85, 0x94, 0xb9, 0x15, 0x86, 0xfe, 0xaa, 0x34, 0xa2, 0x8f, 0xe0, 0x1c, 0x13, 0x8d, 0x2c, 0xdf, + 0x5a, 0xc2, 0x78, 0x5d, 0x30, 0x56, 0x86, 0xb1, 0x5e, 0x96, 0x8c, 0x63, 0x40, 0xa6, 0x85, 0x52, + 0xd6, 0x84, 0xf0, 0x3b, 0x00, 0xe7, 0x29, 0xc3, 0x8f, 0x79, 0x78, 0xde, 0x9e, 0xf6, 0x01, 0xf1, + 0xba, 0x7b, 0x8c, 0x6a, 0x13, 0xa2, 0xad, 0x6e, 0x8d, 0x6d, 0xab, 0x75, 0xe2, 0x88, 0xce, 0xb2, + 0x54, 0x67, 0xa9, 0x34, 0xc6, 0xf1, 0xf0, 0xa6, 0x7a, 0xf7, 0x35, 0x9a, 0x4a, 0x51, 0x52, 0x0b, + 0x29, 0x16, 0x7e, 0x7a, 0x24, 0x39, 0xd0, 0x27, 0x10, 0x52, 0x86, 0x23, 0x66, 0xf3, 0x21, 0xd1, + 0x26, 0x0d, 0x50, 0x2d, 0x2e, 0x97, 0x6b, 0x72, 0x82, 0x6a, 0xc9, 0x04, 0xd5, 0xda, 0xc9, 0x04, + 0x35, 0x6e, 0x2b, 0x5d, 0xb3, 0x23, 0x5d, 0xca, 0xd7, 0x7c, 0xfa, 0x52, 0x07, 0x56, 0x41, 0x18, + 0x38, 0x1c, 0x59, 0x30, 0x4f, 0x02, 0x57, 0xf2, 0xe6, 0x2f, 0xe5, 0xbd, 0xa9, 0x78, 0x67, 0x24, + 0x6f, 0xe2, 0x29, 0x59, 0x27, 0x49, 0xe0, 0x0a, 0xce, 0x0a, 0x84, 0x49, 0xa1, 0x89, 0xab, 0x15, + 0x0c, 0x50, 0xcd, 0x5b, 0x29, 0x0b, 0x3a, 0x80, 0x8b, 0x3e, 0xa6, 0xcc, 0x76, 0x3d, 0xca, 0x22, + 0xaf, 0x33, 0x10, 0x2f, 0x49, 0x28, 0x80, 0x97, 0x2a, 0x78, 0x7b, 0x18, 0xeb, 0xb7, 0x65, 0xf4, + 0xf1, 0x1c, 0x52, 0xcb, 0x3c, 0xbf, 0x5c, 0x4f, 0xdd, 0x09, 0x61, 0x5f, 0x03, 0x38, 0x3b, 0x72, + 0x20, 0xae, 0x78, 0x4f, 0x54, 0x2b, 0x5e, 0xb6, 0x3f, 0xb6, 0x54, 0xd6, 0x9a, 0x8c, 0xfb, 0x2f, + 0x86, 0xab, 0xed, 0x8d, 0x52, 0xca, 0x5f, 0x58, 0x56, 0x66, 0x93, 0xb9, 0xfc, 0xf9, 0xc7, 0xbb, + 0xd7, 0xf9, 0x08, 0x35, 0xcd, 0x3f, 0x01, 0x9c, 0xd9, 0xf4, 0x0e, 0x89, 0xbb, 0xda, 0x0b, 0x07, + 0x01, 0x13, 0x73, 0xfa, 0x08, 0x16, 0xb8, 0x36, 0xb1, 0xb7, 0xc4, 0xb8, 0x16, 0x2f, 0x1e, 0xc4, + 0x64, 0xb8, 0x1b, 0xda, 0x69, 0xac, 0x83, 0x61, 0xac, 0x97, 0xa4, 0xf6, 0x11, 0x81, 0x69, 0xe5, + 0x3b, 0xc9, 0x02, 0xf8, 0x12, 0xc0, 0x1b, 0x72, 0x19, 0x61, 0x11, 0x4d, 0xcb, 0x5e, 0x56, 0x91, + 0xfb, 0xaa, 0x22, 0x73, 0xaa, 0x0f, 0x52, 0xce, 0x57, 0x2b, 0x46, 0x51, 0xb8, 0xca, 0x24, 0x53, + 0xfb, 0xe9, 0x17, 0x00, 0x0b, 0x16, 0x1f, 0xd3, 0x37, 0x9b, 0x38, 0x81, 0x32, 0xbe, 0x1d, 0xf1, + 0x58, 0x72, 0xe1, 0x35, 0xd6, 0x79, 0x6e, 0xbf, 0xc7, 0xfa, 0x3b, 0xaf, 0x37, 0xb4, 0xc3, 0x58, + 0x47, 0xe9, 0x2a, 0x08, 0x2a, 0xd3, 0x82, 0xe2, 0x24, 0x72, 0x48, 0xe5, 0x75, 0x02, 0xe0, 0xe4, + 0x43, 0x39, 0xde, 0x68, 0x13, 0x4e, 0xa8, 0x72, 0x03, 0x11, 0xb7, 0x76, 0x85, 0xb8, 0xcd, 0x80, + 0x59, 0xca, 0x1b, 0x7d, 0x00, 0xa7, 0xc5, 0x38, 0xf3, 0xc5, 0x23, 0x82, 0x8a, 0x3c, 0x72, 0x8d, + 0xa5, 0x61, 0xac, 0x2f, 0xa4, 0xe6, 0x7f, 0x74, 0x6f, 0x5a, 0x53, 0x89, 0x41, 0xfc, 0xe3, 0xa4, + 0xf4, 0x7d, 0x01, 0xa7, 0x1e, 0x0c, 0xc8, 0x80, 0xb8, 0xff, 0xb3, 0xc8, 0x95, 0x1c, 0x0f, 0x61, + 0x7e, 0x0e, 0x6f, 0xb4, 0x43, 0x86, 0xfd, 0x37, 0xc3, 0xfe, 0x13, 0x80, 0xb3, 0x1f, 0x7a, 0x94, + 0x85, 0x91, 0xe7, 0x60, 0xdf, 0x22, 0x07, 0x38, 0x72, 0x29, 0xfa, 0x01, 0xc0, 0xb7, 0x9c, 0x41, + 0x6f, 0xe0, 0x63, 0xe6, 0xed, 0x13, 0x7b, 0x10, 0x78, 0xcc, 0x8e, 0xe4, 0x9d, 0xfa, 0x72, 0xf8, + 0xef, 0x15, 0xbf, 0xa3, 0x5a, 0xbd, 0x22, 0x4b, 0x79, 0x01, 0xd5, 0x95, 0xb7, 0xfc, 0xc2, 0x2b, + 0xa2, 0x9d, 0xc0, 0x63, 0x4a, 0xad, 0xcc, 0xe4, 0xce, 0x57, 0x00, 0xe6, 0x93, 0xbf, 0x52, 0x74, + 0x07, 0x2e, 0xb4, 0xb6, 0x56, 0xb7, 0xed, 0xf6, 0xa7, 0xad, 0x0d, 0x7b, 0x67, 0xfb, 0x61, 0x6b, + 0x63, 0xad, 0xb9, 0xd9, 0xdc, 0x58, 0x2f, 0x65, 0xca, 0x33, 0xc7, 0x27, 0x46, 0x31, 0x01, 0x6e, + 0x7b, 0x3e, 0xaa, 0xc2, 0xd2, 0x2b, 0x6c, 0x6b, 0xa7, 0xb1, 0xd5, 0x5c, 0x2b, 0x81, 0x32, 0x3a, + 0x3e, 0x31, 0xa6, 0x13, 0x58, 0x6b, 0xd0, 0xf1, 0x3d, 0x07, 0xdd, 0x81, 0xb3, 0x29, 0xa4, 0xd5, + 0xfc, 0x78, 0xb5, 0xbd, 0x51, 0xca, 0x96, 0xe7, 0x8e, 0x4f, 0x8c, 0x99, 0x11, 0x54, 0x7e, 0xe0, + 0x94, 0x73, 0x4f, 0xbe, 0xaf, 0x64, 0x1a, 0xf7, 0x5f, 0x9c, 0x55, 0xc0, 0xe9, 0x59, 0x05, 0xfc, + 0x71, 0x56, 0x01, 0x4f, 0xcf, 0x2b, 0x99, 0xd3, 0xf3, 0x4a, 0xe6, 0xd7, 0xf3, 0x4a, 0xe6, 0xb3, + 0xbb, 0xa9, 0xc4, 0xc7, 0x7c, 0x68, 0x1e, 0x8e, 0x9e, 0x44, 0x0d, 0x3a, 0x13, 0x62, 0xad, 0xbf, + 0xf7, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x6c, 0xb8, 0xfd, 0x95, 0x0a, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -517,8 +517,8 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x1a } - if m.EpochDays != 0 { - i = encodeVarintFarming(dAtA, i, uint64(m.EpochDays)) + if m.NextEpochDays != 0 { + i = encodeVarintFarming(dAtA, i, uint64(m.NextEpochDays)) i-- dAtA[i] = 0x10 } @@ -915,8 +915,8 @@ func (m *Params) Size() (n int) { n += 1 + l + sovFarming(uint64(l)) } } - if m.EpochDays != 0 { - n += 1 + sovFarming(uint64(m.EpochDays)) + if m.NextEpochDays != 0 { + n += 1 + sovFarming(uint64(m.NextEpochDays)) } l = len(m.FarmingFeeCollector) if l > 0 { @@ -1131,9 +1131,9 @@ func (m *Params) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field EpochDays", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field NextEpochDays", wireType) } - m.EpochDays = 0 + m.NextEpochDays = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowFarming @@ -1143,7 +1143,7 @@ func (m *Params) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - m.EpochDays |= uint32(b&0x7F) << shift + m.NextEpochDays |= uint32(b&0x7F) << shift if b < 0x80 { break } diff --git a/x/farming/types/genesis_test.go b/x/farming/types/genesis_test.go index 437bac7a..ee050f83 100644 --- a/x/farming/types/genesis_test.go +++ b/x/farming/types/genesis_test.go @@ -23,10 +23,10 @@ func TestValidateGenesis(t *testing.T) { "", }, { - "invalid EpochDays case", + "invalid NextEpochDays case", func(genState *types.GenesisState) { params := types.DefaultParams() - params.EpochDays = 0 + params.NextEpochDays = 0 genState.Params = params }, "epoch days must be positive: 0", diff --git a/x/farming/types/keys_test.go b/x/farming/types/keys_test.go index 456c40a6..7565c29f 100644 --- a/x/farming/types/keys_test.go +++ b/x/farming/types/keys_test.go @@ -137,9 +137,9 @@ func (s *keysTestSuite) TestGetStakingIndexKey() { key := types.GetStakingIndexKey(tc.farmerAcc, tc.stakingCoinDenom) s.Require().Equal(tc.expected, key) - stakingCoinDenom, farmerAcc := types.ParseStakingIndexKey(key) - s.Require().Equal(tc.stakingCoinDenom, stakingCoinDenom) + farmerAcc, stakingCoinDenom := types.ParseStakingIndexKey(key) s.Require().Equal(tc.farmerAcc, farmerAcc) + s.Require().Equal(tc.stakingCoinDenom, stakingCoinDenom) } } diff --git a/x/farming/types/params.go b/x/farming/types/params.go index 90f0f9ed..7fd5f4dc 100644 --- a/x/farming/types/params.go +++ b/x/farming/types/params.go @@ -13,11 +13,11 @@ import ( // Parameter store keys var ( KeyPrivatePlanCreationFee = []byte("PrivatePlanCreationFee") - KeyEpochDays = []byte("EpochDays") + KeyNextEpochDays = []byte("NextEpochDays") KeyFarmingFeeCollector = []byte("FarmingFeeCollector") DefaultPrivatePlanCreationFee = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100_000_000))) - DefaultEpochDays = uint32(1) + DefaultNextEpochDays = uint32(1) DefaultFarmingFeeCollector = sdk.AccAddress(address.Module(ModuleName, []byte("FarmingFeeCollectorAcc"))).String() StakingReserveAcc = sdk.AccAddress(address.Module(ModuleName, []byte("StakingReserveAcc"))) RewardsReserveAcc = sdk.AccAddress(address.Module(ModuleName, []byte("RewardsReserveAcc"))) @@ -34,7 +34,7 @@ func ParamKeyTable() paramstypes.KeyTable { func DefaultParams() Params { return Params{ PrivatePlanCreationFee: DefaultPrivatePlanCreationFee, - EpochDays: DefaultEpochDays, + NextEpochDays: DefaultNextEpochDays, FarmingFeeCollector: DefaultFarmingFeeCollector, } } @@ -43,7 +43,7 @@ func DefaultParams() Params { func (p *Params) ParamSetPairs() paramstypes.ParamSetPairs { return paramstypes.ParamSetPairs{ paramstypes.NewParamSetPair(KeyPrivatePlanCreationFee, &p.PrivatePlanCreationFee, validatePrivatePlanCreationFee), - paramstypes.NewParamSetPair(KeyEpochDays, &p.EpochDays, validateEpochDays), + paramstypes.NewParamSetPair(KeyNextEpochDays, &p.NextEpochDays, validateEpochDays), paramstypes.NewParamSetPair(KeyFarmingFeeCollector, &p.FarmingFeeCollector, validateFarmingFeeCollector), } } @@ -61,7 +61,7 @@ func (p Params) Validate() error { validator func(interface{}) error }{ {p.PrivatePlanCreationFee, validatePrivatePlanCreationFee}, - {p.EpochDays, validateEpochDays}, + {p.NextEpochDays, validateEpochDays}, {p.FarmingFeeCollector, validateFarmingFeeCollector}, } { if err := v.validator(v.value); err != nil { diff --git a/x/farming/types/params_test.go b/x/farming/types/params_test.go index 4d1cec01..9912a5d1 100644 --- a/x/farming/types/params_test.go +++ b/x/farming/types/params_test.go @@ -20,7 +20,7 @@ func TestParams(t *testing.T) { paramsStr := `private_plan_creation_fee: - denom: stake amount: "100000000" -epoch_days: 1 +next_epoch_days: 1 farming_fee_collector: cosmos1h292smhhttwy0rl3qr4p6xsvpvxc4v05s6rxtczwq3cs6qc462mqejwy8x ` require.Equal(t, paramsStr, defaultParams.String()) @@ -44,7 +44,7 @@ func TestParamsValidate(t *testing.T) { { "NegativeEpochDays", func(params *types.Params) { - params.EpochDays = uint32(0) + params.NextEpochDays = uint32(0) }, "epoch days must be positive: 0", }, From dcde75717860e20db6959b960760fb6a2838b6f1 Mon Sep 17 00:00:00 2001 From: kogisin Date: Tue, 14 Sep 2021 15:22:07 +0900 Subject: [PATCH 04/20] test: add more tests and update address to have 20 bytes --- x/farming/types/keys_test.go | 234 +++++++++++++++++++++++------------ 1 file changed, 153 insertions(+), 81 deletions(-) diff --git a/x/farming/types/keys_test.go b/x/farming/types/keys_test.go index 7565c29f..fcfab0f0 100644 --- a/x/farming/types/keys_test.go +++ b/x/farming/types/keys_test.go @@ -1,11 +1,13 @@ package types_test import ( + fmt "fmt" "testing" "github.com/stretchr/testify/suite" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/farming/x/farming/types" ) @@ -19,16 +21,24 @@ func TestKeysTestSuite(t *testing.T) { } func (s *keysTestSuite) TestGetPlanKey() { - s.Require().Equal([]byte{0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa}, types.GetPlanKey(10)) - s.Require().Equal([]byte{0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9}, types.GetPlanKey(9)) s.Require().Equal([]byte{0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, types.GetPlanKey(0)) + s.Require().Equal([]byte{0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9}, types.GetPlanKey(9)) + s.Require().Equal([]byte{0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa}, types.GetPlanKey(10)) } func (s *keysTestSuite) TestGetPlansByFarmerIndexKey() { - s.Require().Equal([]byte{0x12}, types.GetPlansByFarmerIndexKey(sdk.AccAddress(""))) - s.Require().Equal([]byte{0x12, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31}, types.GetPlansByFarmerIndexKey(sdk.AccAddress("farmer1"))) - s.Require().Equal([]byte{0x12, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32}, types.GetPlansByFarmerIndexKey(sdk.AccAddress("farmer2"))) - s.Require().Equal([]byte{0x12, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33}, types.GetPlansByFarmerIndexKey(sdk.AccAddress("farmer3"))) + farmer0 := sdk.AccAddress(crypto.AddressHash([]byte("farmer1"))) + farmer1 := sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))) + farmer2 := sdk.AccAddress(crypto.AddressHash([]byte("farmer3"))) + farmer3 := sdk.AccAddress(crypto.AddressHash([]byte("farmer4"))) + s.Require().Equal([]byte{0x12, 0x14, 0xd3, 0x7a, 0x85, 0xec, 0x75, 0xf, 0x3, 0xaa, 0xe5, + 0x36, 0xcf, 0x1b, 0xb7, 0x59, 0xb7, 0xbc, 0xbd, 0x5c, 0xfe, 0x3d}, types.GetPlansByFarmerIndexKey(farmer0)) + s.Require().Equal([]byte{0x12, 0x14, 0x15, 0x1, 0x20, 0x25, 0x5a, 0x5d, 0xe8, 0x6b, 0xa1, + 0xed, 0xfb, 0x6f, 0x45, 0x48, 0xcb, 0xfb, 0x6f, 0x28, 0x66, 0xf3}, types.GetPlansByFarmerIndexKey(farmer1)) + s.Require().Equal([]byte{0x12, 0x14, 0xdf, 0xb0, 0x6d, 0xbf, 0xc6, 0x9a, 0xcd, 0xf5, 0x7b, + 0xb, 0xe7, 0x69, 0x75, 0x50, 0x9e, 0x69, 0x54, 0xa6, 0x1e, 0xe2}, types.GetPlansByFarmerIndexKey(farmer2)) + s.Require().Equal([]byte{0x12, 0x14, 0x98, 0x94, 0x3f, 0x57, 0x25, 0xab, 0x66, 0xef, 0x46, + 0x63, 0x4a, 0xfe, 0xeb, 0x8, 0xc0, 0x4a, 0x53, 0x25, 0x2c, 0x9f}, types.GetPlansByFarmerIndexKey(farmer3)) } func (s *keysTestSuite) TestGetPlanByFarmerAddrIndexKey() { @@ -38,24 +48,22 @@ func (s *keysTestSuite) TestGetPlanByFarmerAddrIndexKey() { expected []byte }{ { - nil, - 1, - []byte{0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, - }, - { - sdk.AccAddress("farmer1"), + sdk.AccAddress(crypto.AddressHash([]byte("farmer1"))), 1, - []byte{0x12, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, + []byte{0x12, 0x14, 0xd3, 0x7a, 0x85, 0xec, 0x75, 0xf, 0x3, 0xaa, 0xe5, 0x36, 0xcf, 0x1b, 0xb7, + 0x59, 0xb7, 0xbc, 0xbd, 0x5c, 0xfe, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, }, { - sdk.AccAddress("farmer2"), + sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))), 2, - []byte{0x12, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, + []byte{0x12, 0x14, 0x15, 0x1, 0x20, 0x25, 0x5a, 0x5d, 0xe8, 0x6b, 0xa1, 0xed, 0xfb, 0x6f, 0x45, + 0x48, 0xcb, 0xfb, 0x6f, 0x28, 0x66, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, }, { - sdk.AccAddress("farmer3"), + sdk.AccAddress(crypto.AddressHash([]byte("farmer3"))), 2, - []byte{0x12, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, + []byte{0x12, 0x14, 0xdf, 0xb0, 0x6d, 0xbf, 0xc6, 0x9a, 0xcd, 0xf5, 0x7b, 0xb, 0xe7, 0x69, 0x75, + 0x50, 0x9e, 0x69, 0x54, 0xa6, 0x1e, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, }, } @@ -70,26 +78,23 @@ func (s *keysTestSuite) TestGetStakingKey() { farmerAcc sdk.AccAddress expected []byte }{ - // TODO: see the first case of TestGetStakingIndexKey - { - sdk.DefaultBondDenom, - sdk.AccAddress(""), - []byte{0x21, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65}, - }, { sdk.DefaultBondDenom, - sdk.AccAddress("farmer1"), - []byte{0x21, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31}, + sdk.AccAddress(crypto.AddressHash([]byte("farmer1"))), + []byte{0x21, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0xd3, 0x7a, 0x85, 0xec, 0x75, 0xf, 0x3, + 0xaa, 0xe5, 0x36, 0xcf, 0x1b, 0xb7, 0x59, 0xb7, 0xbc, 0xbd, 0x5c, 0xfe, 0x3d}, }, { sdk.DefaultBondDenom, - sdk.AccAddress("farmer2"), - []byte{0x21, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32}, + sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))), + []byte{0x21, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x15, 0x1, 0x20, 0x25, 0x5a, 0x5d, 0xe8, + 0x6b, 0xa1, 0xed, 0xfb, 0x6f, 0x45, 0x48, 0xcb, 0xfb, 0x6f, 0x28, 0x66, 0xf3}, }, { sdk.DefaultBondDenom, - sdk.AccAddress("farmer3"), - []byte{0x21, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33}, + sdk.AccAddress(crypto.AddressHash([]byte("farmer3"))), + []byte{0x21, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0xdf, 0xb0, 0x6d, 0xbf, 0xc6, 0x9a, 0xcd, + 0xf5, 0x7b, 0xb, 0xe7, 0x69, 0x75, 0x50, 0x9e, 0x69, 0x54, 0xa6, 0x1e, 0xe2}, }, } @@ -104,32 +109,29 @@ func (s *keysTestSuite) TestGetStakingKey() { } func (s *keysTestSuite) TestGetStakingIndexKey() { + testCases := []struct { farmerAcc sdk.AccAddress stakingCoinDenom string expected []byte }{ - // TODO: should we cover only happy cases? below case returns panic since farmerAcc is empty - // How about the case1 for TestGetStakingKey()? It allows empty farmerAcc. - // { - // sdk.AccAddress(""), - // sdk.DefaultBondDenom, - // []byte{0x22, 0x73, 0x74, 0x61, 0x6b, 0x65}, - // }, { - sdk.AccAddress("farmer1"), + sdk.AccAddress(crypto.AddressHash([]byte("farmer1"))), sdk.DefaultBondDenom, - []byte{0x22, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31, 0x73, 0x74, 0x61, 0x6b, 0x65}, + []byte{0x22, 0x14, 0xd3, 0x7a, 0x85, 0xec, 0x75, 0xf, 0x3, 0xaa, 0xe5, 0x36, 0xcf, + 0x1b, 0xb7, 0x59, 0xb7, 0xbc, 0xbd, 0x5c, 0xfe, 0x3d, 0x73, 0x74, 0x61, 0x6b, 0x65}, }, { - sdk.AccAddress("farmer2"), + sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))), sdk.DefaultBondDenom, - []byte{0x22, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32, 0x73, 0x74, 0x61, 0x6b, 0x65}, + []byte{0x22, 0x14, 0x15, 0x1, 0x20, 0x25, 0x5a, 0x5d, 0xe8, 0x6b, 0xa1, 0xed, 0xfb, + 0x6f, 0x45, 0x48, 0xcb, 0xfb, 0x6f, 0x28, 0x66, 0xf3, 0x73, 0x74, 0x61, 0x6b, 0x65}, }, { - sdk.AccAddress("farmer3"), + sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))), sdk.DefaultBondDenom, - []byte{0x22, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33, 0x73, 0x74, 0x61, 0x6b, 0x65}, + []byte{0x22, 0x14, 0x15, 0x1, 0x20, 0x25, 0x5a, 0x5d, 0xe8, 0x6b, 0xa1, 0xed, 0xfb, + 0x6f, 0x45, 0x48, 0xcb, 0xfb, 0x6f, 0x28, 0x66, 0xf3, 0x73, 0x74, 0x61, 0x6b, 0x65}, }, } @@ -144,10 +146,18 @@ func (s *keysTestSuite) TestGetStakingIndexKey() { } func (s *keysTestSuite) TestGetStakingsByFarmerPrefix() { - s.Require().Equal([]byte{0x22}, types.GetStakingsByFarmerPrefix(sdk.AccAddress(""))) - s.Require().Equal([]byte{0x22, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31}, types.GetStakingsByFarmerPrefix(sdk.AccAddress("farmer1"))) - s.Require().Equal([]byte{0x22, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32}, types.GetStakingsByFarmerPrefix(sdk.AccAddress("farmer2"))) - s.Require().Equal([]byte{0x22, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33}, types.GetStakingsByFarmerPrefix(sdk.AccAddress("farmer3"))) + farmer0 := sdk.AccAddress(crypto.AddressHash([]byte("farmer1"))) + farmer1 := sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))) + farmer2 := sdk.AccAddress(crypto.AddressHash([]byte("farmer3"))) + farmer3 := sdk.AccAddress(crypto.AddressHash([]byte("farmer4"))) + s.Require().Equal([]byte{0x22, 0x14, 0xd3, 0x7a, 0x85, 0xec, 0x75, 0xf, 0x3, 0xaa, 0xe5, + 0x36, 0xcf, 0x1b, 0xb7, 0x59, 0xb7, 0xbc, 0xbd, 0x5c, 0xfe, 0x3d}, types.GetStakingsByFarmerPrefix(farmer0)) + s.Require().Equal([]byte{0x22, 0x14, 0x15, 0x1, 0x20, 0x25, 0x5a, 0x5d, 0xe8, 0x6b, 0xa1, + 0xed, 0xfb, 0x6f, 0x45, 0x48, 0xcb, 0xfb, 0x6f, 0x28, 0x66, 0xf3}, types.GetStakingsByFarmerPrefix(farmer1)) + s.Require().Equal([]byte{0x22, 0x14, 0xdf, 0xb0, 0x6d, 0xbf, 0xc6, 0x9a, 0xcd, 0xf5, 0x7b, + 0xb, 0xe7, 0x69, 0x75, 0x50, 0x9e, 0x69, 0x54, 0xa6, 0x1e, 0xe2}, types.GetStakingsByFarmerPrefix(farmer2)) + s.Require().Equal([]byte{0x22, 0x14, 0x98, 0x94, 0x3f, 0x57, 0x25, 0xab, 0x66, 0xef, 0x46, + 0x63, 0x4a, 0xfe, 0xeb, 0x8, 0xc0, 0x4a, 0x53, 0x25, 0x2c, 0x9f}, types.GetStakingsByFarmerPrefix(farmer3)) } func (s *keysTestSuite) TestGetQueuedStakingKey() { @@ -158,28 +168,31 @@ func (s *keysTestSuite) TestGetQueuedStakingKey() { }{ { sdk.DefaultBondDenom, - nil, - []byte{0x23, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65}, - }, - { - sdk.DefaultBondDenom, - sdk.AccAddress("farmer1"), - []byte{0x23, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31}, + sdk.AccAddress(crypto.AddressHash([]byte("farmer1"))), + []byte{0x23, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0xd3, 0x7a, 0x85, 0xec, 0x75, 0xf, 0x3, + 0xaa, 0xe5, 0x36, 0xcf, 0x1b, 0xb7, 0x59, 0xb7, 0xbc, 0xbd, 0x5c, 0xfe, 0x3d}, }, { sdk.DefaultBondDenom, - sdk.AccAddress("farmer2"), - []byte{0x23, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32}, + sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))), + []byte{0x23, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x15, 0x1, 0x20, 0x25, 0x5a, 0x5d, 0xe8, + 0x6b, 0xa1, 0xed, 0xfb, 0x6f, 0x45, 0x48, 0xcb, 0xfb, 0x6f, 0x28, 0x66, 0xf3}, }, { sdk.DefaultBondDenom, - sdk.AccAddress("farmer3"), - []byte{0x23, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33}, + sdk.AccAddress(crypto.AddressHash([]byte("farmer3"))), + []byte{0x23, 0x5, 0x73, 0x74, 0x61, 0x6b, 0x65, 0xdf, 0xb0, 0x6d, 0xbf, 0xc6, 0x9a, 0xcd, + 0xf5, 0x7b, 0xb, 0xe7, 0x69, 0x75, 0x50, 0x9e, 0x69, 0x54, 0xa6, 0x1e, 0xe2}, }, } for _, tc := range testCases { - s.Require().Equal(tc.expected, types.GetQueuedStakingKey(tc.stakingCoinDenom, tc.farmerAcc)) + key := types.GetQueuedStakingKey(tc.stakingCoinDenom, tc.farmerAcc) + s.Require().Equal(tc.expected, key) + + stakingCoinDenom, farmerAcc := types.ParseQueuedStakingKey(key) + s.Require().Equal(tc.stakingCoinDenom, stakingCoinDenom) + s.Require().Equal(tc.farmerAcc, farmerAcc) } } @@ -190,38 +203,52 @@ func (s *keysTestSuite) TestGetQueuedStakingIndexKey() { expected []byte }{ { - sdk.AccAddress(""), + sdk.AccAddress(crypto.AddressHash([]byte("farmer1"))), sdk.DefaultBondDenom, - []byte{0x24, 0x73, 0x74, 0x61, 0x6b, 0x65}, + []byte{0x24, 0x14, 0xd3, 0x7a, 0x85, 0xec, 0x75, 0xf, 0x3, 0xaa, 0xe5, 0x36, 0xcf, 0x1b, + 0xb7, 0x59, 0xb7, 0xbc, 0xbd, 0x5c, 0xfe, 0x3d, 0x73, 0x74, 0x61, 0x6b, 0x65}, }, { - sdk.AccAddress("farmer1"), + sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))), sdk.DefaultBondDenom, - []byte{0x24, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31, 0x73, 0x74, 0x61, 0x6b, 0x65}, + []byte{0x24, 0x14, 0x15, 0x1, 0x20, 0x25, 0x5a, 0x5d, 0xe8, 0x6b, 0xa1, 0xed, 0xfb, 0x6f, + 0x45, 0x48, 0xcb, 0xfb, 0x6f, 0x28, 0x66, 0xf3, 0x73, 0x74, 0x61, 0x6b, 0x65}, }, { - sdk.AccAddress("farmer2"), + sdk.AccAddress(crypto.AddressHash([]byte("farmer3"))), sdk.DefaultBondDenom, - []byte{0x24, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32, 0x73, 0x74, 0x61, 0x6b, 0x65}, - }, - { - sdk.AccAddress("farmer3"), - sdk.DefaultBondDenom, - []byte{0x24, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33, 0x73, 0x74, 0x61, 0x6b, 0x65}, + []byte{0x24, 0x14, 0xdf, 0xb0, 0x6d, 0xbf, 0xc6, 0x9a, 0xcd, 0xf5, 0x7b, 0xb, 0xe7, 0x69, + 0x75, 0x50, 0x9e, 0x69, 0x54, 0xa6, 0x1e, 0xe2, 0x73, 0x74, 0x61, 0x6b, 0x65}, }, } for _, tc := range testCases { key := types.GetQueuedStakingIndexKey(tc.farmerAcc, tc.stakingCoinDenom) s.Require().Equal(tc.expected, key) + + farmerAcc, stakingCoinDenom := types.ParseQueuedStakingIndexKey(key) + s.Require().Equal(tc.farmerAcc, farmerAcc) + s.Require().Equal(tc.stakingCoinDenom, stakingCoinDenom) } } func (s *keysTestSuite) TestGetQueuedStakingByFarmerPrefix() { - s.Require().Equal([]byte{0x24}, types.GetQueuedStakingByFarmerPrefix(sdk.AccAddress(""))) - s.Require().Equal([]byte{0x24, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x31}, types.GetQueuedStakingByFarmerPrefix(sdk.AccAddress("farmer1"))) - s.Require().Equal([]byte{0x24, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x32}, types.GetQueuedStakingByFarmerPrefix(sdk.AccAddress("farmer2"))) - s.Require().Equal([]byte{0x24, 0x7, 0x66, 0x61, 0x72, 0x6d, 0x65, 0x72, 0x33}, types.GetQueuedStakingByFarmerPrefix(sdk.AccAddress("farmer3"))) + farmer0 := sdk.AccAddress(crypto.AddressHash([]byte("farmer1"))) + farmer1 := sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))) + farmer2 := sdk.AccAddress(crypto.AddressHash([]byte("farmer3"))) + farmer3 := sdk.AccAddress(crypto.AddressHash([]byte("farmer4"))) + s.Require().Equal([]byte{0x24, 0x14, 0xd3, 0x7a, 0x85, 0xec, 0x75, + 0xf, 0x3, 0xaa, 0xe5, 0x36, 0xcf, 0x1b, 0xb7, 0x59, 0xb7, 0xbc, + 0xbd, 0x5c, 0xfe, 0x3d}, types.GetQueuedStakingByFarmerPrefix(farmer0)) + s.Require().Equal([]byte{0x24, 0x14, 0x15, 0x1, 0x20, 0x25, 0x5a, + 0x5d, 0xe8, 0x6b, 0xa1, 0xed, 0xfb, 0x6f, 0x45, 0x48, 0xcb, + 0xfb, 0x6f, 0x28, 0x66, 0xf3}, types.GetQueuedStakingByFarmerPrefix(farmer1)) + s.Require().Equal([]byte{0x24, 0x14, 0xdf, 0xb0, 0x6d, 0xbf, 0xc6, + 0x9a, 0xcd, 0xf5, 0x7b, 0xb, 0xe7, 0x69, 0x75, 0x50, 0x9e, 0x69, + 0x54, 0xa6, 0x1e, 0xe2}, types.GetQueuedStakingByFarmerPrefix(farmer2)) + s.Require().Equal([]byte{0x24, 0x14, 0x98, 0x94, 0x3f, 0x57, 0x25, + 0xab, 0x66, 0xef, 0x46, 0x63, 0x4a, 0xfe, 0xeb, 0x8, 0xc0, 0x4a, + 0x53, 0x25, 0x2c, 0x9f}, types.GetQueuedStakingByFarmerPrefix(farmer3)) } func (s *keysTestSuite) TestGetTotalStakingKey() { @@ -235,11 +262,6 @@ func (s *keysTestSuite) TestGetHistoricalRewardsKey() { epoch uint64 expected []byte }{ - { - "", - 0, - []byte{0x31, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, - }, { sdk.DefaultBondDenom, 1, @@ -253,11 +275,61 @@ func (s *keysTestSuite) TestGetHistoricalRewardsKey() { } for _, tc := range testCases { - s.Require().Equal(tc.expected, types.GetHistoricalRewardsKey(tc.stakingCoinDenom, tc.epoch)) + key := types.GetHistoricalRewardsKey(tc.stakingCoinDenom, tc.epoch) + s.Require().Equal(tc.expected, key) + + stakingCoinDenom, epoch := types.ParseHistoricalRewardsKey(key) + s.Require().Equal(tc.stakingCoinDenom, stakingCoinDenom) + s.Require().Equal(tc.epoch, epoch) } } func (s *keysTestSuite) TestGetCurrentEpochKey() { - s.Require().Equal([]byte{0x32}, types.GetCurrentEpochKey("")) - s.Require().Equal([]byte{0x32, 0x73, 0x74, 0x61, 0x6b, 0x65}, types.GetCurrentEpochKey(sdk.DefaultBondDenom)) + // key0 + stakingCoinDenom0 := "" + key0 := types.GetCurrentEpochKey(stakingCoinDenom0) + s.Require().Equal([]byte{0x32}, key0) + + stakingCoinDenom := types.ParseCurrentEpochKey(key0) + s.Require().Equal(stakingCoinDenom, stakingCoinDenom0) + + // key1 + stakingCoinDenom1 := sdk.DefaultBondDenom + key1 := types.GetCurrentEpochKey(stakingCoinDenom1) + s.Require().Equal([]byte{0x32, 0x73, 0x74, 0x61, 0x6b, 0x65}, key1) + + stakingCoinDenom = types.ParseCurrentEpochKey(key1) + s.Require().Equal(stakingCoinDenom, stakingCoinDenom1) +} + +func (s *keysTestSuite) TestLengthPrefix() { + denom0 := sdk.DefaultBondDenom + denom1 := "uatom" + + testCases := []struct { + stakingCoinDenom string + length int + expected []byte + }{ + { + denom0, + len(denom0), + []byte{0x5, 0x73, 0x74, 0x61, 0x6b, 0x65}, + }, + { + denom1, + len(denom1), + []byte{0x5, 0x75, 0x61, 0x74, 0x6f, 0x6d}, + }, + } + + for _, tc := range testCases { + bz := types.LengthPrefixString(tc.stakingCoinDenom) + s.Require().Equal(tc.length, int(bz[0])) + s.Require().Equal(tc.expected, bz) + } + + t1 := sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))) + fmt.Println("t1: ", t1) + fmt.Println("len: ", len(t1)) } From 75b527a88d39885fd108b449c06b76599372b56a Mon Sep 17 00:00:00 2001 From: kogisin Date: Tue, 14 Sep 2021 15:22:32 +0900 Subject: [PATCH 05/20] test: remove comments --- x/farming/types/keys_test.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/x/farming/types/keys_test.go b/x/farming/types/keys_test.go index fcfab0f0..17291f5c 100644 --- a/x/farming/types/keys_test.go +++ b/x/farming/types/keys_test.go @@ -1,7 +1,6 @@ package types_test import ( - fmt "fmt" "testing" "github.com/stretchr/testify/suite" @@ -328,8 +327,4 @@ func (s *keysTestSuite) TestLengthPrefix() { s.Require().Equal(tc.length, int(bz[0])) s.Require().Equal(tc.expected, bz) } - - t1 := sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))) - fmt.Println("t1: ", t1) - fmt.Println("len: ", len(t1)) } From 3f128ad623c7c943a965903f20c9e913207c67b2 Mon Sep 17 00:00:00 2001 From: kogisin Date: Tue, 14 Sep 2021 17:05:35 +0900 Subject: [PATCH 06/20] test: update epoch days to next epoch days --- x/farming/simulation/genesis.go | 16 ++++++++-------- x/farming/simulation/genesis_test.go | 2 +- x/farming/simulation/operations_test.go | 2 +- x/farming/simulation/params.go | 4 ++-- x/farming/simulation/params_test.go | 2 +- x/farming/simulation/proposals_test.go | 1 - 6 files changed, 13 insertions(+), 14 deletions(-) diff --git a/x/farming/simulation/genesis.go b/x/farming/simulation/genesis.go index ac5b9fdf..5ebe9702 100644 --- a/x/farming/simulation/genesis.go +++ b/x/farming/simulation/genesis.go @@ -17,7 +17,7 @@ import ( // Simulation parameter constants. const ( PrivatePlanCreationFee = "private_plan_creation_fee" - EpochDays = "epoch_days" + NextEpochDays = "next_epoch_days" FarmingFeeCollector = "farming_fee_collector" ) @@ -26,9 +26,9 @@ func GenPrivatePlanCreationFee(r *rand.Rand) sdk.Coins { return sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, int64(simulation.RandIntBetween(r, 0, 100_000_000)))) } -// GenEpochDays return default epoch days. -func GenEpochDays(r *rand.Rand) uint32 { - return uint32(simulation.RandIntBetween(r, int(types.DefaultEpochDays), 10)) +// GenNextEpochDays return default next epoch days. +func GenNextEpochDays(r *rand.Rand) uint32 { + return uint32(simulation.RandIntBetween(r, int(types.DefaultNextEpochDays), 10)) } // GenFarmingFeeCollector returns default farming fee collector. @@ -44,10 +44,10 @@ func RandomizedGenState(simState *module.SimulationState) { func(r *rand.Rand) { privatePlanCreationFee = GenPrivatePlanCreationFee(r) }, ) - var epochDays uint32 + var nextEpochDays uint32 simState.AppParams.GetOrGenerate( - simState.Cdc, EpochDays, &epochDays, simState.Rand, - func(r *rand.Rand) { epochDays = GenEpochDays(r) }, + simState.Cdc, NextEpochDays, &nextEpochDays, simState.Rand, + func(r *rand.Rand) { nextEpochDays = GenNextEpochDays(r) }, ) var feeCollector string @@ -59,7 +59,7 @@ func RandomizedGenState(simState *module.SimulationState) { farmingGenesis := types.GenesisState{ Params: types.Params{ PrivatePlanCreationFee: privatePlanCreationFee, - EpochDays: epochDays, + NextEpochDays: nextEpochDays, FarmingFeeCollector: feeCollector, }, } diff --git a/x/farming/simulation/genesis_test.go b/x/farming/simulation/genesis_test.go index 727d7993..a41aa1cd 100644 --- a/x/farming/simulation/genesis_test.go +++ b/x/farming/simulation/genesis_test.go @@ -45,7 +45,7 @@ func TestRandomizedGenState(t *testing.T) { dec4 := "cosmos1h292smhhttwy0rl3qr4p6xsvpvxc4v05s6rxtczwq3cs6qc462mqejwy8x" require.Equal(t, dec1, genState.Params.PrivatePlanCreationFee) - require.Equal(t, dec3, genState.Params.EpochDays) + require.Equal(t, dec3, genState.Params.NextEpochDays) require.Equal(t, dec4, genState.Params.FarmingFeeCollector) } diff --git a/x/farming/simulation/operations_test.go b/x/farming/simulation/operations_test.go index 54e2015e..7258322d 100644 --- a/x/farming/simulation/operations_test.go +++ b/x/farming/simulation/operations_test.go @@ -222,7 +222,7 @@ func TestSimulateMsgHarvest(t *testing.T) { // setup epoch days to 1 to ease the test params := app.FarmingKeeper.GetParams(ctx) - params.EpochDays = 1 + params.NextEpochDays = 1 app.FarmingKeeper.SetParams(ctx, params) // setup a fixed amount plan diff --git a/x/farming/simulation/params.go b/x/farming/simulation/params.go index e10a36a6..3bf27b0d 100644 --- a/x/farming/simulation/params.go +++ b/x/farming/simulation/params.go @@ -25,9 +25,9 @@ func ParamChanges(r *rand.Rand) []simtypes.ParamChange { return string(bz) }, ), - simulation.NewSimParamChange(types.ModuleName, string(types.KeyEpochDays), + simulation.NewSimParamChange(types.ModuleName, string(types.KeyNextEpochDays), func(r *rand.Rand) string { - return fmt.Sprintf("%d", GenEpochDays(r)) + return fmt.Sprintf("%d", GenNextEpochDays(r)) }, ), simulation.NewSimParamChange(types.ModuleName, string(types.KeyFarmingFeeCollector), diff --git a/x/farming/simulation/params_test.go b/x/farming/simulation/params_test.go index fd93cd39..9faeee47 100644 --- a/x/farming/simulation/params_test.go +++ b/x/farming/simulation/params_test.go @@ -20,7 +20,7 @@ func TestParamChanges(t *testing.T) { subspace string }{ {"farming/PrivatePlanCreationFee", "PrivatePlanCreationFee", "[{\"denom\":\"stake\",\"amount\":\"98498081\"}]", "farming"}, - {"farming/EpochDays", "EpochDays", "7", "farming"}, + {"farming/NextEpochDays", "NextEpochDays", "7", "farming"}, {"farming/FarmingFeeCollector", "FarmingFeeCollector", "\"cosmos1h292smhhttwy0rl3qr4p6xsvpvxc4v05s6rxtczwq3cs6qc462mqejwy8x\"", "farming"}, } diff --git a/x/farming/simulation/proposals_test.go b/x/farming/simulation/proposals_test.go index 24e81bd5..33ac035b 100644 --- a/x/farming/simulation/proposals_test.go +++ b/x/farming/simulation/proposals_test.go @@ -80,5 +80,4 @@ func TestProposalContents(t *testing.T) { require.Equal(t, "MBcObErwgTDNGWnwQMUgFFSKtPDMEoEQCTKVREqrXZSGLqwTMcxHfWotDllNkIJPMbXzjDVjPOOjCFuIvTyhXKLyhUScOXvYthRX", content2.GetDescription()) require.Equal(t, "farming", content2.ProposalRoute()) require.Equal(t, "PublicPlan", content2.ProposalType()) - } From 95009e011977d9802ce0287ef4cd98acb7600f68 Mon Sep 17 00:00:00 2001 From: kogisin Date: Tue, 14 Sep 2021 18:31:55 +0900 Subject: [PATCH 07/20] test: add handler tests --- x/farming/handler_test.go | 97 +++++++++++++++++++++++++++++++++------ 1 file changed, 84 insertions(+), 13 deletions(-) diff --git a/x/farming/handler_test.go b/x/farming/handler_test.go index 67192d63..7fd153e8 100644 --- a/x/farming/handler_test.go +++ b/x/farming/handler_test.go @@ -140,26 +140,97 @@ func TestMsgStake(t *testing.T) { } func TestMsgUnstake(t *testing.T) { - // app, ctx, addrs := createTestInput() + app, ctx, addrs := createTestInput() + + // stake some amount + err := app.FarmingKeeper.Stake(ctx, addrs[0], sdk.NewCoins(sdk.NewInt64Coin(denom1, 10_000_000))) + require.NoError(t, err) + + _, found := app.FarmingKeeper.GetQueuedStaking(ctx, denom1, addrs[0]) + require.Equal(t, true, found) - // err := app.FarmingKeeper.Stake(ctx, addrs[0], sdk.NewCoins(sdk.NewInt64Coin(denom1, 10_000_000))) - // require.NoError(t, err) + // check balance before unstake + balanceBefore := app.BankKeeper.GetBalance(ctx, addrs[0], denom1) + require.Equal(t, sdk.NewInt(990_000_000), balanceBefore.Amount) - // _, found := app.FarmingKeeper.GetQueuedStaking(ctx, denom1, addrs[0]) - // require.Equal(t, true, found) + msg := types.NewMsgUnstake( + addrs[0], + sdk.NewCoins(sdk.NewInt64Coin(denom1, 5_000_000)), + ) - // msg := types.NewMsgUnstake( - // addrs[0], - // sdk.NewCoins(sdk.NewInt64Coin(denom1, 5_000_000)), - // ) + handler := farming.NewHandler(app.FarmingKeeper) + _, err = handler(ctx, msg) + require.NoError(t, err) - // handler := farming.NewHandler(app.FarmingKeeper) - // _, err = handler(ctx, msg) - // require.NoError(t, err) + // check balance after unstake + balanceAfter := app.BankKeeper.GetBalance(ctx, addrs[0], denom1) + require.Equal(t, sdk.NewInt(995_000_000), balanceAfter.Amount) } func TestMsgHarvest(t *testing.T) { - // TODO: not implemented yet + app, ctx, addrs := createTestInput() + creator := addrs[0] // use addrs[0] to create a fixed amount plan + staker := addrs[1] // use addrs[1] to stake some amount with staking coin denom + + planMsg := types.NewMsgCreateFixedAmountPlan( + "handler-test", + creator, + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(10, 1)), // 100% + ), + mustParseRFC3339("2021-08-02T00:00:00Z"), + mustParseRFC3339("2021-08-10T00:00:00Z"), + sdk.NewCoins(sdk.NewInt64Coin(denom3, 77_000_000)), + ) + + // create a fixed amount plan + plan, err := app.FarmingKeeper.CreateFixedAmountPlan( + ctx, + planMsg, + creator, + creator, + types.PlanTypePrivate, + ) + require.NoError(t, err) + + _, found := app.FarmingKeeper.GetPlan(ctx, plan.GetId()) + require.Equal(t, true, found) + + // stake some amount + err = app.FarmingKeeper.Stake( + ctx, + staker, + sdk.NewCoins(sdk.NewInt64Coin(denom1, 10_000_000)), + ) + require.NoError(t, err) + + _, found = app.FarmingKeeper.GetQueuedStaking(ctx, denom1, staker) + require.Equal(t, true, found) + + // move queued coins into staked coins + app.FarmingKeeper.ProcessQueuedCoins(ctx) + + _, found = app.FarmingKeeper.GetStaking(ctx, denom1, staker) + require.Equal(t, true, found) + + // check balances before unstake + balanceBefore := app.BankKeeper.GetBalance(ctx, staker, denom3) + require.Equal(t, sdk.NewInt(1_000_000_000), balanceBefore.Amount) + + // allocate rewards + ctx = ctx.WithBlockTime(mustParseRFC3339("2021-08-05T00:00:00Z")) + err = app.FarmingKeeper.AllocateRewards(ctx) + require.NoError(t, err) + + // harvest + msg := types.NewMsgHarvest(staker, []string{denom1}) + handler := farming.NewHandler(app.FarmingKeeper) + _, err = handler(ctx, msg) + require.NoError(t, err) + + // check balances after unstake + balanceAfter := app.BankKeeper.GetBalance(ctx, staker, denom3) + require.Equal(t, sdk.NewInt(1_077_000_000), balanceAfter.Amount) } func mustParseRFC3339(s string) time.Time { From 4e191167b69edaf41d009791551516e0722429b7 Mon Sep 17 00:00:00 2001 From: kogisin Date: Tue, 14 Sep 2021 19:07:32 +0900 Subject: [PATCH 08/20] refactor: add comment for global current epoch days --- x/farming/abci.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/x/farming/abci.go b/x/farming/abci.go index f132c5fd..a79c97f9 100644 --- a/x/farming/abci.go +++ b/x/farming/abci.go @@ -21,6 +21,9 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) { } } + // GlobalCurrentEpochDays is used here to proceed the next logics instead of + // global parameter NextEpochDays to prevent from affecting the epoch days when allocating farming rewards + // NextEpochDays can be changed through governance proposal during the allocation currentEpochDays := k.GetGlobalCurrentEpochDays(ctx) lastEpochTime, found := k.GetLastEpochTime(ctx) From 4a216b76f7129037b8358654c384c60e72cb35b5 Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 15 Sep 2021 12:48:42 +0900 Subject: [PATCH 09/20] test: apply module testing suit --- x/farming/abci_test.go | 17 +++ x/farming/handler_test.go | 257 ++++++++++----------------------- x/farming/keeper/msg_server.go | 2 + x/farming/module_test.go | 154 ++++++++++++++++++++ 4 files changed, 250 insertions(+), 180 deletions(-) create mode 100644 x/farming/abci_test.go create mode 100644 x/farming/module_test.go diff --git a/x/farming/abci_test.go b/x/farming/abci_test.go new file mode 100644 index 00000000..6b8e6376 --- /dev/null +++ b/x/farming/abci_test.go @@ -0,0 +1,17 @@ +package farming_test + +import ( + "github.com/tendermint/farming/x/farming" + + _ "github.com/stretchr/testify/suite" +) + +func (suite *ModuleTestSuite) TestEndBlocker() { + params := suite.keeper.GetParams(suite.ctx) + suite.Require().Equal(uint32(1), params.NextEpochDays) + + suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-08-11T23:59:59Z")) + farming.EndBlocker(suite.ctx, suite.keeper) + + // WIP +} diff --git a/x/farming/handler_test.go b/x/farming/handler_test.go index 7fd153e8..bfe2a487 100644 --- a/x/farming/handler_test.go +++ b/x/farming/handler_test.go @@ -1,65 +1,18 @@ package farming_test import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - sdk "github.com/cosmos/cosmos-sdk/types" - tmproto "github.com/tendermint/tendermint/proto/tendermint/types" - simapp "github.com/tendermint/farming/app" "github.com/tendermint/farming/x/farming" - "github.com/tendermint/farming/x/farming/keeper" "github.com/tendermint/farming/x/farming/types" -) - -const ( - denom1 = "denom1" - denom2 = "denom2" - denom3 = "denom3" -) -var ( - initialBalances = sdk.NewCoins( - sdk.NewInt64Coin(sdk.DefaultBondDenom, 1_000_000_000), - sdk.NewInt64Coin(denom1, 1_000_000_000), - sdk.NewInt64Coin(denom2, 1_000_000_000), - sdk.NewInt64Coin(denom3, 1_000_000_000)) + _ "github.com/stretchr/testify/suite" ) -// createTestInput returns a simapp with custom FarmingKeeper -// to avoid messing with the hooks. -func createTestInput() (*simapp.FarmingApp, sdk.Context, []sdk.AccAddress) { - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, tmproto.Header{}) - - app.FarmingKeeper = keeper.NewKeeper( - app.AppCodec(), - app.GetKey(types.StoreKey), - app.GetSubspace(types.ModuleName), - app.AccountKeeper, - app.BankKeeper, - map[string]bool{}, - ) - - addrs := simapp.AddTestAddrs(app, ctx, 6, sdk.ZeroInt()) - for _, addr := range addrs { - if err := simapp.FundAccount(app.BankKeeper, ctx, addr, initialBalances); err != nil { - panic(err) - } - } - - return app, ctx, addrs -} - -func TestMsgCreateFixedAmountPlan(t *testing.T) { - app, ctx, addrs := createTestInput() - +func (suite *ModuleTestSuite) TestMsgCreateFixedAmountPlan() { msg := types.NewMsgCreateFixedAmountPlan( - "handler-test", - addrs[0], + "handlerTestPlan1", + suite.addrs[0], sdk.NewDecCoins( sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% @@ -69,28 +22,26 @@ func TestMsgCreateFixedAmountPlan(t *testing.T) { sdk.NewCoins(sdk.NewInt64Coin(denom3, 10_000_000)), ) - handler := farming.NewHandler(app.FarmingKeeper) - _, err := handler(ctx, msg) - require.NoError(t, err) + handler := farming.NewHandler(suite.keeper) + _, err := handler(suite.ctx, msg) + suite.Require().NoError(err) - plan, found := app.FarmingKeeper.GetPlan(ctx, 1) - require.Equal(t, true, found) + plan, found := suite.keeper.GetPlan(suite.ctx, 1) + suite.Require().Equal(true, found) - require.Equal(t, msg.Name, plan.GetName()) - require.Equal(t, msg.Creator, plan.GetTerminationAddress().String()) - require.Equal(t, msg.StakingCoinWeights, plan.GetStakingCoinWeights()) - require.Equal(t, types.PrivatePlanFarmingPoolAddress(msg.Name, 1), plan.GetFarmingPoolAddress()) - require.Equal(t, mustParseRFC3339("2021-08-02T00:00:00Z"), plan.GetStartTime()) - require.Equal(t, mustParseRFC3339("2021-08-10T00:00:00Z"), plan.GetEndTime()) - require.Equal(t, msg.EpochAmount, plan.(*types.FixedAmountPlan).EpochAmount) + suite.Require().Equal(msg.Name, plan.GetName()) + suite.Require().Equal(msg.Creator, plan.GetTerminationAddress().String()) + suite.Require().Equal(msg.StakingCoinWeights, plan.GetStakingCoinWeights()) + suite.Require().Equal(types.PrivatePlanFarmingPoolAddress(msg.Name, 1), plan.GetFarmingPoolAddress()) + suite.Require().Equal(mustParseRFC3339("2021-08-02T00:00:00Z"), plan.GetStartTime()) + suite.Require().Equal(mustParseRFC3339("2021-08-10T00:00:00Z"), plan.GetEndTime()) + suite.Require().Equal(msg.EpochAmount, plan.(*types.FixedAmountPlan).EpochAmount) } -func TestMsgCreateRatioPlan(t *testing.T) { - app, ctx, addrs := createTestInput() - +func (suite *ModuleTestSuite) TestMsgCreateRatioPlan() { msg := types.NewMsgCreateRatioPlan( - "handler-test", - addrs[0], + "handlerTestPlan2", + suite.addrs[0], sdk.NewDecCoins( sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% @@ -100,143 +51,89 @@ func TestMsgCreateRatioPlan(t *testing.T) { sdk.NewDecWithPrec(4, 2), // 4%, ) - handler := farming.NewHandler(app.FarmingKeeper) - _, err := handler(ctx, msg) - require.NoError(t, err) + handler := farming.NewHandler(suite.keeper) + _, err := handler(suite.ctx, msg) + suite.Require().NoError(err) - plan, found := app.FarmingKeeper.GetPlan(ctx, 1) - require.Equal(t, true, found) + plan, found := suite.keeper.GetPlan(suite.ctx, 1) + suite.Require().Equal(true, found) - require.Equal(t, msg.Name, plan.GetName()) - require.Equal(t, msg.Creator, plan.GetTerminationAddress().String()) - require.Equal(t, msg.StakingCoinWeights, plan.GetStakingCoinWeights()) - require.Equal(t, types.PrivatePlanFarmingPoolAddress(msg.Name, 1), plan.GetFarmingPoolAddress()) - require.Equal(t, mustParseRFC3339("2021-08-02T00:00:00Z"), plan.GetStartTime()) - require.Equal(t, mustParseRFC3339("2021-08-10T00:00:00Z"), plan.GetEndTime()) - require.Equal(t, msg.EpochRatio, plan.(*types.RatioPlan).EpochRatio) + suite.Require().Equal(msg.Name, plan.GetName()) + suite.Require().Equal(msg.Creator, plan.GetTerminationAddress().String()) + suite.Require().Equal(msg.StakingCoinWeights, plan.GetStakingCoinWeights()) + suite.Require().Equal(types.PrivatePlanFarmingPoolAddress(msg.Name, 1), plan.GetFarmingPoolAddress()) + suite.Require().Equal(mustParseRFC3339("2021-08-02T00:00:00Z"), plan.GetStartTime()) + suite.Require().Equal(mustParseRFC3339("2021-08-10T00:00:00Z"), plan.GetEndTime()) + suite.Require().Equal(msg.EpochRatio, plan.(*types.RatioPlan).EpochRatio) } -func TestMsgStake(t *testing.T) { - app, ctx, addrs := createTestInput() - +func (suite *ModuleTestSuite) TestMsgStake() { msg := types.NewMsgStake( - addrs[0], + suite.addrs[0], sdk.NewCoins(sdk.NewInt64Coin(denom1, 10_000_000)), ) - handler := farming.NewHandler(app.FarmingKeeper) - _, err := handler(ctx, msg) - require.NoError(t, err) + handler := farming.NewHandler(suite.keeper) + _, err := handler(suite.ctx, msg) + suite.Require().NoError(err) - _, found := app.FarmingKeeper.GetQueuedStaking(ctx, denom1, addrs[0]) - require.Equal(t, true, found) + _, found := suite.keeper.GetQueuedStaking(suite.ctx, denom1, suite.addrs[0]) + suite.Require().Equal(true, found) queuedCoins := sdk.NewCoins() - app.FarmingKeeper.IterateQueuedStakingsByFarmer(ctx, addrs[0], func(stakingCoinDenom string, queuedStaking types.QueuedStaking) (stop bool) { - queuedCoins = queuedCoins.Add(sdk.NewCoin(stakingCoinDenom, queuedStaking.Amount)) - return false - }) - require.Equal(t, msg.StakingCoins, queuedCoins) + suite.keeper.IterateQueuedStakingsByFarmer(suite.ctx, suite.addrs[0], + func(stakingCoinDenom string, queuedStaking types.QueuedStaking) (stop bool) { + queuedCoins = queuedCoins.Add(sdk.NewCoin(stakingCoinDenom, queuedStaking.Amount)) + return false + }, + ) + suite.Require().Equal(msg.StakingCoins, queuedCoins) } -func TestMsgUnstake(t *testing.T) { - app, ctx, addrs := createTestInput() +func (suite *ModuleTestSuite) TestMsgUnstake() { + stakeCoin := sdk.NewInt64Coin(denom1, 10_000_000) + suite.Stake(suite.addrs[0], sdk.NewCoins(stakeCoin)) - // stake some amount - err := app.FarmingKeeper.Stake(ctx, addrs[0], sdk.NewCoins(sdk.NewInt64Coin(denom1, 10_000_000))) - require.NoError(t, err) + _, found := suite.keeper.GetQueuedStaking(suite.ctx, denom1, suite.addrs[0]) + suite.Require().Equal(true, found) - _, found := app.FarmingKeeper.GetQueuedStaking(ctx, denom1, addrs[0]) - require.Equal(t, true, found) + balancesBefore := suite.app.BankKeeper.GetAllBalances(suite.ctx, suite.addrs[0]) - // check balance before unstake - balanceBefore := app.BankKeeper.GetBalance(ctx, addrs[0], denom1) - require.Equal(t, sdk.NewInt(990_000_000), balanceBefore.Amount) - - msg := types.NewMsgUnstake( - addrs[0], - sdk.NewCoins(sdk.NewInt64Coin(denom1, 5_000_000)), - ) + unstakeCoin := sdk.NewInt64Coin(denom1, 5_000_000) + msg := types.NewMsgUnstake(suite.addrs[0], sdk.NewCoins(unstakeCoin)) - handler := farming.NewHandler(app.FarmingKeeper) - _, err = handler(ctx, msg) - require.NoError(t, err) + handler := farming.NewHandler(suite.keeper) + _, err := handler(suite.ctx, msg) + suite.Require().NoError(err) - // check balance after unstake - balanceAfter := app.BankKeeper.GetBalance(ctx, addrs[0], denom1) - require.Equal(t, sdk.NewInt(995_000_000), balanceAfter.Amount) + balancesAfter := suite.app.BankKeeper.GetAllBalances(suite.ctx, suite.addrs[0]) + suite.Require().True(coinsEq(balancesBefore.Add(unstakeCoin), balancesAfter)) } -func TestMsgHarvest(t *testing.T) { - app, ctx, addrs := createTestInput() - creator := addrs[0] // use addrs[0] to create a fixed amount plan - staker := addrs[1] // use addrs[1] to stake some amount with staking coin denom - - planMsg := types.NewMsgCreateFixedAmountPlan( - "handler-test", - creator, - sdk.NewDecCoins( - sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(10, 1)), // 100% - ), - mustParseRFC3339("2021-08-02T00:00:00Z"), - mustParseRFC3339("2021-08-10T00:00:00Z"), - sdk.NewCoins(sdk.NewInt64Coin(denom3, 77_000_000)), - ) - - // create a fixed amount plan - plan, err := app.FarmingKeeper.CreateFixedAmountPlan( - ctx, - planMsg, - creator, - creator, - types.PlanTypePrivate, - ) - require.NoError(t, err) - - _, found := app.FarmingKeeper.GetPlan(ctx, plan.GetId()) - require.Equal(t, true, found) - - // stake some amount - err = app.FarmingKeeper.Stake( - ctx, - staker, - sdk.NewCoins(sdk.NewInt64Coin(denom1, 10_000_000)), - ) - require.NoError(t, err) - - _, found = app.FarmingKeeper.GetQueuedStaking(ctx, denom1, staker) - require.Equal(t, true, found) +func (suite *ModuleTestSuite) TestMsgHarvest() { + for _, plan := range suite.samplePlans { + suite.keeper.SetPlan(suite.ctx, plan) + } - // move queued coins into staked coins - app.FarmingKeeper.ProcessQueuedCoins(ctx) + suite.Stake(suite.addrs[0], sdk.NewCoins(sdk.NewInt64Coin(denom2, 10_000_000))) + suite.keeper.ProcessQueuedCoins(suite.ctx) - _, found = app.FarmingKeeper.GetStaking(ctx, denom1, staker) - require.Equal(t, true, found) + balancesBefore := suite.app.BankKeeper.GetAllBalances(suite.ctx, suite.addrs[0]) - // check balances before unstake - balanceBefore := app.BankKeeper.GetBalance(ctx, staker, denom3) - require.Equal(t, sdk.NewInt(1_000_000_000), balanceBefore.Amount) + suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-08-05T00:00:00Z")) + err := suite.keeper.AllocateRewards(suite.ctx) + suite.Require().NoError(err) - // allocate rewards - ctx = ctx.WithBlockTime(mustParseRFC3339("2021-08-05T00:00:00Z")) - err = app.FarmingKeeper.AllocateRewards(ctx) - require.NoError(t, err) + rewards := suite.Rewards(suite.addrs[0]) - // harvest - msg := types.NewMsgHarvest(staker, []string{denom1}) - handler := farming.NewHandler(app.FarmingKeeper) - _, err = handler(ctx, msg) - require.NoError(t, err) + msg := types.NewMsgHarvest(suite.addrs[0], []string{denom2}) - // check balances after unstake - balanceAfter := app.BankKeeper.GetBalance(ctx, staker, denom3) - require.Equal(t, sdk.NewInt(1_077_000_000), balanceAfter.Amount) -} + handler := farming.NewHandler(suite.keeper) + _, err = handler(suite.ctx, msg) + suite.Require().NoError(err) -func mustParseRFC3339(s string) time.Time { - t, err := time.Parse(time.RFC3339, s) - if err != nil { - panic(err) - } - return t + balancesAfter := suite.app.BankKeeper.GetAllBalances(suite.ctx, suite.addrs[0]) + suite.Require().True(coinsEq(balancesBefore.Add(rewards...), balancesAfter)) + suite.Require().True(suite.app.BankKeeper.GetAllBalances(suite.ctx, suite.keeper.GetRewardsReservePoolAcc(suite.ctx)).IsZero()) + suite.Require().True(suite.Rewards(suite.addrs[0]).IsZero()) } diff --git a/x/farming/keeper/msg_server.go b/x/farming/keeper/msg_server.go index 61a1fd2e..491c45c1 100644 --- a/x/farming/keeper/msg_server.go +++ b/x/farming/keeper/msg_server.go @@ -7,6 +7,7 @@ package keeper import ( "context" + "fmt" sdk "github.com/cosmos/cosmos-sdk/types" @@ -38,6 +39,7 @@ func (k msgServer) CreateFixedAmountPlan(goCtx context.Context, msg *types.MsgCr } plans := k.GetAllPlans(ctx) + fmt.Println("plans: ", len(plans)) if err := types.ValidateName(plans); err != nil { return nil, err } diff --git a/x/farming/module_test.go b/x/farming/module_test.go new file mode 100644 index 00000000..e4c156b6 --- /dev/null +++ b/x/farming/module_test.go @@ -0,0 +1,154 @@ +package farming_test + +import ( + "testing" + "time" + + "github.com/stretchr/testify/suite" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + + simapp "github.com/tendermint/farming/app" + "github.com/tendermint/farming/x/farming/keeper" + "github.com/tendermint/farming/x/farming/types" +) + +const ( + denom1 = "denom1" // staking coin denom 1 + denom2 = "denom2" // staking coin denom 2 + denom3 = "denom3" // epoch amount for a fixed amount plan +) + +var ( + initialBalances = sdk.NewCoins( + sdk.NewInt64Coin(sdk.DefaultBondDenom, 1_000_000_000), + sdk.NewInt64Coin(denom1, 1_000_000_000), + sdk.NewInt64Coin(denom2, 1_000_000_000), + sdk.NewInt64Coin(denom3, 1_000_000_000)) +) + +type ModuleTestSuite struct { + suite.Suite + + app *simapp.FarmingApp + ctx sdk.Context + keeper keeper.Keeper + querier keeper.Querier + addrs []sdk.AccAddress + sampleFixedAmtPlans []types.PlanI + sampleRatioPlans []types.PlanI + samplePlans []types.PlanI +} + +func TestModuleTestSuite(t *testing.T) { + suite.Run(t, new(ModuleTestSuite)) +} + +func (suite *ModuleTestSuite) SetupTest() { + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, tmproto.Header{}) + + suite.app = app + suite.ctx = ctx + suite.keeper = suite.app.FarmingKeeper + suite.querier = keeper.Querier{Keeper: suite.keeper} + suite.addrs = simapp.AddTestAddrs(suite.app, suite.ctx, 6, sdk.ZeroInt()) + for _, addr := range suite.addrs { + err := simapp.FundAccount(suite.app.BankKeeper, suite.ctx, addr, initialBalances) + suite.Require().NoError(err) + } + suite.sampleFixedAmtPlans = []types.PlanI{ + types.NewFixedAmountPlan( + types.NewBasePlan( + 1, + "testPlan1", + types.PlanTypePrivate, + suite.addrs[4].String(), + suite.addrs[4].String(), + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% + sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% + ), + mustParseRFC3339("2021-08-02T00:00:00Z"), + mustParseRFC3339("2021-08-10T00:00:00Z"), + ), + sdk.NewCoins(sdk.NewInt64Coin(denom3, 1_000_000)), + ), + types.NewFixedAmountPlan( + types.NewBasePlan( + 2, + "testPlan2", + types.PlanTypePublic, + suite.addrs[5].String(), + suite.addrs[5].String(), + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.OneDec()), // 100% + ), + mustParseRFC3339("2021-08-04T00:00:00Z"), + mustParseRFC3339("2021-08-12T00:00:00Z"), + ), + sdk.NewCoins(sdk.NewInt64Coin(denom3, 2_000_000)), + ), + } + suite.sampleRatioPlans = []types.PlanI{ + types.NewRatioPlan( + types.NewBasePlan( + 3, + "testPlan3", + types.PlanTypePrivate, + suite.addrs[4].String(), + suite.addrs[4].String(), + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(5, 1)), // 50% + sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(5, 1)), // 50% + ), + mustParseRFC3339("2021-08-01T00:00:00Z"), + mustParseRFC3339("2021-08-09T00:00:00Z"), + ), + sdk.NewDecWithPrec(4, 2), // 4% + ), + types.NewRatioPlan( + types.NewBasePlan( + 4, + "testPlan4", + types.PlanTypePublic, + suite.addrs[5].String(), + suite.addrs[5].String(), + sdk.NewDecCoins( + sdk.NewDecCoinFromDec(denom2, sdk.OneDec()), // 100% + ), + mustParseRFC3339("2021-08-03T00:00:00Z"), + mustParseRFC3339("2021-08-07T00:00:00Z"), + ), + sdk.NewDecWithPrec(3, 2), // 3% + ), + } + suite.samplePlans = append(suite.sampleFixedAmtPlans, suite.sampleRatioPlans...) +} + +// Stake is a convenient method to test Keeper.Stake. +func (suite *ModuleTestSuite) Stake(farmerAcc sdk.AccAddress, amt sdk.Coins) { + err := suite.keeper.Stake(suite.ctx, farmerAcc, amt) + suite.Require().NoError(err) +} + +// Rewards is a convenient method to test Keeper.WithdrawAllRewards. +func (suite *ModuleTestSuite) Rewards(farmerAcc sdk.AccAddress) sdk.Coins { + cacheCtx, _ := suite.ctx.CacheContext() + rewards, err := suite.keeper.WithdrawAllRewards(cacheCtx, farmerAcc) + suite.Require().NoError(err) + return rewards +} + +func coinsEq(exp, got sdk.Coins) (bool, string, string, string) { + return exp.IsEqual(got), "expected:\t%v\ngot:\t\t%v", exp.String(), got.String() +} + +func mustParseRFC3339(s string) time.Time { + t, err := time.Parse(time.RFC3339, s) + if err != nil { + panic(err) + } + return t +} From f8a0bd59aa5913fd10f8d1e15ce177ee1b7f1c07 Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 15 Sep 2021 13:21:55 +0900 Subject: [PATCH 10/20] test: remove tests for deprecated PlansByFarmerIndex --- x/farming/types/keys_test.go | 46 ------------------------------------ 1 file changed, 46 deletions(-) diff --git a/x/farming/types/keys_test.go b/x/farming/types/keys_test.go index 17291f5c..71c45dd8 100644 --- a/x/farming/types/keys_test.go +++ b/x/farming/types/keys_test.go @@ -25,52 +25,6 @@ func (s *keysTestSuite) TestGetPlanKey() { s.Require().Equal([]byte{0x11, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa}, types.GetPlanKey(10)) } -func (s *keysTestSuite) TestGetPlansByFarmerIndexKey() { - farmer0 := sdk.AccAddress(crypto.AddressHash([]byte("farmer1"))) - farmer1 := sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))) - farmer2 := sdk.AccAddress(crypto.AddressHash([]byte("farmer3"))) - farmer3 := sdk.AccAddress(crypto.AddressHash([]byte("farmer4"))) - s.Require().Equal([]byte{0x12, 0x14, 0xd3, 0x7a, 0x85, 0xec, 0x75, 0xf, 0x3, 0xaa, 0xe5, - 0x36, 0xcf, 0x1b, 0xb7, 0x59, 0xb7, 0xbc, 0xbd, 0x5c, 0xfe, 0x3d}, types.GetPlansByFarmerIndexKey(farmer0)) - s.Require().Equal([]byte{0x12, 0x14, 0x15, 0x1, 0x20, 0x25, 0x5a, 0x5d, 0xe8, 0x6b, 0xa1, - 0xed, 0xfb, 0x6f, 0x45, 0x48, 0xcb, 0xfb, 0x6f, 0x28, 0x66, 0xf3}, types.GetPlansByFarmerIndexKey(farmer1)) - s.Require().Equal([]byte{0x12, 0x14, 0xdf, 0xb0, 0x6d, 0xbf, 0xc6, 0x9a, 0xcd, 0xf5, 0x7b, - 0xb, 0xe7, 0x69, 0x75, 0x50, 0x9e, 0x69, 0x54, 0xa6, 0x1e, 0xe2}, types.GetPlansByFarmerIndexKey(farmer2)) - s.Require().Equal([]byte{0x12, 0x14, 0x98, 0x94, 0x3f, 0x57, 0x25, 0xab, 0x66, 0xef, 0x46, - 0x63, 0x4a, 0xfe, 0xeb, 0x8, 0xc0, 0x4a, 0x53, 0x25, 0x2c, 0x9f}, types.GetPlansByFarmerIndexKey(farmer3)) -} - -func (s *keysTestSuite) TestGetPlanByFarmerAddrIndexKey() { - testCases := []struct { - farmerAcc sdk.AccAddress - planID uint64 - expected []byte - }{ - { - sdk.AccAddress(crypto.AddressHash([]byte("farmer1"))), - 1, - []byte{0x12, 0x14, 0xd3, 0x7a, 0x85, 0xec, 0x75, 0xf, 0x3, 0xaa, 0xe5, 0x36, 0xcf, 0x1b, 0xb7, - 0x59, 0xb7, 0xbc, 0xbd, 0x5c, 0xfe, 0x3d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1}, - }, - { - sdk.AccAddress(crypto.AddressHash([]byte("farmer2"))), - 2, - []byte{0x12, 0x14, 0x15, 0x1, 0x20, 0x25, 0x5a, 0x5d, 0xe8, 0x6b, 0xa1, 0xed, 0xfb, 0x6f, 0x45, - 0x48, 0xcb, 0xfb, 0x6f, 0x28, 0x66, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, - }, - { - sdk.AccAddress(crypto.AddressHash([]byte("farmer3"))), - 2, - []byte{0x12, 0x14, 0xdf, 0xb0, 0x6d, 0xbf, 0xc6, 0x9a, 0xcd, 0xf5, 0x7b, 0xb, 0xe7, 0x69, 0x75, - 0x50, 0x9e, 0x69, 0x54, 0xa6, 0x1e, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, - }, - } - - for _, tc := range testCases { - s.Require().Equal(tc.expected, types.GetPlanByFarmerAddrIndexKey(tc.farmerAcc, tc.planID)) - } -} - func (s *keysTestSuite) TestGetStakingKey() { testCases := []struct { stakingCoinDenom string From f3c6df638ccdcb0794719d7cdd0d440d3cfbd06c Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 15 Sep 2021 19:27:37 +0900 Subject: [PATCH 11/20] feat: move mustParseRFC3339 function to utils #109 --- x/farming/client/cli/cli_test.go | 62 ++++++++++------------- x/farming/handler_test.go | 18 +++---- x/farming/keeper/epoch_test.go | 9 ++-- x/farming/keeper/genesis.go | 1 + x/farming/keeper/genesis_test.go | 10 ++-- x/farming/keeper/invariants_test.go | 10 ++-- x/farming/keeper/keeper_test.go | 25 +++------ x/farming/keeper/proposal_handler_test.go | 44 ++++++++-------- x/farming/keeper/reward_test.go | 38 +++++++------- x/farming/keeper/simulation_test.go | 6 +-- x/farming/module_test.go | 25 +++------ x/farming/simulation/operations_test.go | 13 +---- x/farming/simulation/proposals_test.go | 4 +- x/farming/types/plan_test.go | 12 +---- x/farming/types/utils.go | 12 +++++ 15 files changed, 130 insertions(+), 159 deletions(-) create mode 100644 x/farming/types/utils.go diff --git a/x/farming/client/cli/cli_test.go b/x/farming/client/cli/cli_test.go index fe940a7b..a8bb7e5c 100644 --- a/x/farming/client/cli/cli_test.go +++ b/x/farming/client/cli/cli_test.go @@ -5,7 +5,6 @@ package cli_test import ( "fmt" "testing" - "time" "github.com/gogo/protobuf/proto" "github.com/stretchr/testify/suite" @@ -19,6 +18,7 @@ import ( "github.com/tendermint/farming/x/farming/client/cli" farmingtestutil "github.com/tendermint/farming/x/farming/client/testutil" + "github.com/tendermint/farming/x/farming/types" farmingtypes "github.com/tendermint/farming/x/farming/types" ) @@ -82,8 +82,8 @@ func (s *IntegrationTestSuite) TestNewCreateFixedAmountPlanCmd() { case1 := cli.PrivateFixedPlanRequest{ Name: name, StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("0001-01-01T00:00:00Z"), - EndTime: mustParseRFC3339("9999-01-01T00:00:00Z"), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), } @@ -94,8 +94,8 @@ func (s *IntegrationTestSuite) TestNewCreateFixedAmountPlanCmd() { OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM`, StakingCoinWeights: sdk.NewDecCoins(), - StartTime: mustParseRFC3339("0001-01-01T00:00:00Z"), - EndTime: mustParseRFC3339("9999-01-01T00:00:00Z"), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), } @@ -103,8 +103,8 @@ func (s *IntegrationTestSuite) TestNewCreateFixedAmountPlanCmd() { case3 := cli.PrivateFixedPlanRequest{ Name: name, StakingCoinWeights: sdk.NewDecCoins(), - StartTime: mustParseRFC3339("0001-01-01T00:00:00Z"), - EndTime: mustParseRFC3339("9999-01-01T00:00:00Z"), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), } @@ -112,8 +112,8 @@ func (s *IntegrationTestSuite) TestNewCreateFixedAmountPlanCmd() { case4 := cli.PrivateFixedPlanRequest{ Name: name, StakingCoinWeights: sdk.NewDecCoins(sdk.NewDecCoin("poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4", sdk.NewInt(2))), - StartTime: mustParseRFC3339("0001-01-01T00:00:00Z"), - EndTime: mustParseRFC3339("9999-01-01T00:00:00Z"), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), } @@ -121,8 +121,8 @@ func (s *IntegrationTestSuite) TestNewCreateFixedAmountPlanCmd() { case5 := cli.PrivateFixedPlanRequest{ Name: name, StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("2021-08-13T00:00:00Z"), - EndTime: mustParseRFC3339("2021-08-06T00:00:00Z"), + StartTime: types.ParseTime("2021-08-13T00:00:00Z"), + EndTime: types.ParseTime("2021-08-06T00:00:00Z"), EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 100_000_000)), } @@ -130,8 +130,8 @@ func (s *IntegrationTestSuite) TestNewCreateFixedAmountPlanCmd() { case6 := cli.PrivateFixedPlanRequest{ Name: name, StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("0001-01-01T00:00:00Z"), - EndTime: mustParseRFC3339("9999-01-01T00:00:00Z"), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("uatom", 0)), } @@ -247,8 +247,8 @@ func (s *IntegrationTestSuite) TestNewCreateRatioPlanCmd() { case1 := cli.PrivateRatioPlanRequest{ Name: name, StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("0001-01-01T00:00:00Z"), - EndTime: mustParseRFC3339("9999-01-01T00:00:00Z"), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), EpochRatio: sdk.MustNewDecFromStr("0.1"), } @@ -259,8 +259,8 @@ func (s *IntegrationTestSuite) TestNewCreateRatioPlanCmd() { OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM OVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERMOVERMAXLENGTHOVERMAXLENGTHOVERMAXLENGTHOVERM`, StakingCoinWeights: sdk.NewDecCoins(), - StartTime: mustParseRFC3339("0001-01-01T00:00:00Z"), - EndTime: mustParseRFC3339("9999-01-01T00:00:00Z"), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), EpochRatio: sdk.MustNewDecFromStr("0.1"), } @@ -268,8 +268,8 @@ func (s *IntegrationTestSuite) TestNewCreateRatioPlanCmd() { case3 := cli.PrivateRatioPlanRequest{ Name: name, StakingCoinWeights: sdk.NewDecCoins(), - StartTime: mustParseRFC3339("0001-01-01T00:00:00Z"), - EndTime: mustParseRFC3339("9999-01-01T00:00:00Z"), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), EpochRatio: sdk.MustNewDecFromStr("0.1"), } @@ -277,8 +277,8 @@ func (s *IntegrationTestSuite) TestNewCreateRatioPlanCmd() { case4 := cli.PrivateRatioPlanRequest{ Name: name, StakingCoinWeights: sdk.NewDecCoins(sdk.NewDecCoin("poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4", sdk.NewInt(2))), - StartTime: mustParseRFC3339("0001-01-01T00:00:00Z"), - EndTime: mustParseRFC3339("9999-01-01T00:00:00Z"), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), EpochRatio: sdk.MustNewDecFromStr("0.1"), } @@ -286,8 +286,8 @@ func (s *IntegrationTestSuite) TestNewCreateRatioPlanCmd() { case5 := cli.PrivateRatioPlanRequest{ Name: name, StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("2021-08-13T00:00:00Z"), - EndTime: mustParseRFC3339("2021-08-06T00:00:00Z"), + StartTime: types.ParseTime("2021-08-13T00:00:00Z"), + EndTime: types.ParseTime("2021-08-06T00:00:00Z"), EpochRatio: sdk.MustNewDecFromStr("0.1"), } @@ -295,8 +295,8 @@ func (s *IntegrationTestSuite) TestNewCreateRatioPlanCmd() { case6 := cli.PrivateRatioPlanRequest{ Name: name, StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("0001-01-01T00:00:00Z"), - EndTime: mustParseRFC3339("9999-01-01T00:00:00Z"), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), EpochRatio: sdk.MustNewDecFromStr("1.1"), } @@ -525,8 +525,8 @@ func (s *IntegrationTestSuite) TestNewHarvestCmd() { req := cli.PrivateFixedPlanRequest{ Name: "test", StakingCoinWeights: sdk.NewDecCoins(sdk.NewDecCoin("stake", sdk.NewInt(1))), - StartTime: mustParseRFC3339("0001-01-01T00:00:00Z"), - EndTime: mustParseRFC3339("9999-01-01T00:00:00Z"), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), EpochAmount: sdk.NewCoins(sdk.NewInt64Coin("node0token", 100_000_000)), } @@ -601,11 +601,3 @@ func (s *IntegrationTestSuite) TestNewHarvestCmd() { }) } } - -func mustParseRFC3339(s string) time.Time { - t, err := time.Parse(time.RFC3339, s) - if err != nil { - panic(err) - } - return t -} diff --git a/x/farming/handler_test.go b/x/farming/handler_test.go index bfe2a487..02db8628 100644 --- a/x/farming/handler_test.go +++ b/x/farming/handler_test.go @@ -17,8 +17,8 @@ func (suite *ModuleTestSuite) TestMsgCreateFixedAmountPlan() { sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% ), - mustParseRFC3339("2021-08-02T00:00:00Z"), - mustParseRFC3339("2021-08-10T00:00:00Z"), + types.ParseTime("2021-08-02T00:00:00Z"), + types.ParseTime("2021-08-10T00:00:00Z"), sdk.NewCoins(sdk.NewInt64Coin(denom3, 10_000_000)), ) @@ -33,8 +33,8 @@ func (suite *ModuleTestSuite) TestMsgCreateFixedAmountPlan() { suite.Require().Equal(msg.Creator, plan.GetTerminationAddress().String()) suite.Require().Equal(msg.StakingCoinWeights, plan.GetStakingCoinWeights()) suite.Require().Equal(types.PrivatePlanFarmingPoolAddress(msg.Name, 1), plan.GetFarmingPoolAddress()) - suite.Require().Equal(mustParseRFC3339("2021-08-02T00:00:00Z"), plan.GetStartTime()) - suite.Require().Equal(mustParseRFC3339("2021-08-10T00:00:00Z"), plan.GetEndTime()) + suite.Require().Equal(types.ParseTime("2021-08-02T00:00:00Z"), plan.GetStartTime()) + suite.Require().Equal(types.ParseTime("2021-08-10T00:00:00Z"), plan.GetEndTime()) suite.Require().Equal(msg.EpochAmount, plan.(*types.FixedAmountPlan).EpochAmount) } @@ -46,8 +46,8 @@ func (suite *ModuleTestSuite) TestMsgCreateRatioPlan() { sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% ), - mustParseRFC3339("2021-08-02T00:00:00Z"), - mustParseRFC3339("2021-08-10T00:00:00Z"), + types.ParseTime("2021-08-02T00:00:00Z"), + types.ParseTime("2021-08-10T00:00:00Z"), sdk.NewDecWithPrec(4, 2), // 4%, ) @@ -62,8 +62,8 @@ func (suite *ModuleTestSuite) TestMsgCreateRatioPlan() { suite.Require().Equal(msg.Creator, plan.GetTerminationAddress().String()) suite.Require().Equal(msg.StakingCoinWeights, plan.GetStakingCoinWeights()) suite.Require().Equal(types.PrivatePlanFarmingPoolAddress(msg.Name, 1), plan.GetFarmingPoolAddress()) - suite.Require().Equal(mustParseRFC3339("2021-08-02T00:00:00Z"), plan.GetStartTime()) - suite.Require().Equal(mustParseRFC3339("2021-08-10T00:00:00Z"), plan.GetEndTime()) + suite.Require().Equal(types.ParseTime("2021-08-02T00:00:00Z"), plan.GetStartTime()) + suite.Require().Equal(types.ParseTime("2021-08-10T00:00:00Z"), plan.GetEndTime()) suite.Require().Equal(msg.EpochRatio, plan.(*types.RatioPlan).EpochRatio) } @@ -120,7 +120,7 @@ func (suite *ModuleTestSuite) TestMsgHarvest() { balancesBefore := suite.app.BankKeeper.GetAllBalances(suite.ctx, suite.addrs[0]) - suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-08-05T00:00:00Z")) + suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-08-05T00:00:00Z")) err := suite.keeper.AllocateRewards(suite.ctx) suite.Require().NoError(err) diff --git a/x/farming/keeper/epoch_test.go b/x/farming/keeper/epoch_test.go index ac0c1c82..384b0502 100644 --- a/x/farming/keeper/epoch_test.go +++ b/x/farming/keeper/epoch_test.go @@ -5,6 +5,7 @@ import ( "time" "github.com/tendermint/farming/x/farming" + "github.com/tendermint/farming/x/farming/types" _ "github.com/stretchr/testify/suite" ) @@ -13,7 +14,7 @@ func (suite *KeeperTestSuite) TestLastEpochTime() { _, found := suite.keeper.GetLastEpochTime(suite.ctx) suite.Require().False(found) - t := mustParseRFC3339("2021-07-23T05:01:02Z") + t := types.ParseTime("2021-07-23T05:01:02Z") suite.keeper.SetLastEpochTime(suite.ctx, t) t2, found := suite.keeper.GetLastEpochTime(suite.ctx) @@ -30,12 +31,12 @@ func (suite *KeeperTestSuite) TestFirstEpoch() { params := suite.keeper.GetParams(suite.ctx) suite.Require().Equal(uint32(1), params.NextEpochDays) - suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-08-11T23:59:59Z")) + suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-08-11T23:59:59Z")) farming.EndBlocker(suite.ctx, suite.keeper) lastEpochTime, found := suite.keeper.GetLastEpochTime(suite.ctx) suite.Require().True(found) - suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-08-12T00:00:00Z")) + 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. @@ -50,7 +51,7 @@ func (suite *KeeperTestSuite) TestEpochDays() { params.NextEpochDays = epochDays suite.keeper.SetParams(suite.ctx, params) - t := mustParseRFC3339("2021-08-11T00:00:00Z") + t := types.ParseTime("2021-08-11T00:00:00Z") suite.ctx = suite.ctx.WithBlockTime(t) farming.EndBlocker(suite.ctx, suite.keeper) diff --git a/x/farming/keeper/genesis.go b/x/farming/keeper/genesis.go index 6888bd24..d37a4d38 100644 --- a/x/farming/keeper/genesis.go +++ b/x/farming/keeper/genesis.go @@ -11,6 +11,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) { ctx, applyCache := ctx.CacheContext() k.SetParams(ctx, genState.Params) + k.SetGlobalCurrentEpochDays(ctx, genState.Params.NextEpochDays) moduleAcc := k.accountKeeper.GetModuleAccount(ctx, types.ModuleName) k.accountKeeper.SetModuleAccount(ctx, moduleAcc) diff --git a/x/farming/keeper/genesis_test.go b/x/farming/keeper/genesis_test.go index 2a15f2fa..ad687e82 100644 --- a/x/farming/keeper/genesis_test.go +++ b/x/farming/keeper/genesis_test.go @@ -20,8 +20,8 @@ func (suite *KeeperTestSuite) TestInitGenesis() { sdk.NewDecCoins( sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1))), - mustParseRFC3339("2021-07-30T00:00:00Z"), - mustParseRFC3339("2021-08-30T00:00:00Z"), + types.ParseTime("2021-07-30T00:00:00Z"), + types.ParseTime("2021-08-30T00:00:00Z"), ), sdk.NewCoins(sdk.NewInt64Coin(denom3, 1_000_000))), types.NewRatioPlan( @@ -34,8 +34,8 @@ func (suite *KeeperTestSuite) TestInitGenesis() { sdk.NewDecCoins( sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1))), - mustParseRFC3339("2021-07-30T00:00:00Z"), - mustParseRFC3339("2021-08-30T00:00:00Z"), + types.ParseTime("2021-07-30T00:00:00Z"), + types.ParseTime("2021-08-30T00:00:00Z"), ), sdk.MustNewDecFromStr("0.01")), } @@ -50,7 +50,7 @@ func (suite *KeeperTestSuite) TestInitGenesis() { sdk.NewInt64Coin(denom2, 1_000_000))) suite.keeper.ProcessQueuedCoins(suite.ctx) - suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-07-31T00:00:00Z")) + suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-07-31T00:00:00Z")) // Advance 2 epochs err := suite.keeper.AdvanceEpoch(suite.ctx) diff --git a/x/farming/keeper/invariants_test.go b/x/farming/keeper/invariants_test.go index 68728f67..5cd64947 100644 --- a/x/farming/keeper/invariants_test.go +++ b/x/farming/keeper/invariants_test.go @@ -12,8 +12,8 @@ package keeper_test // sdk.NewDecCoins( // sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1))), -// mustParseRFC3339("2021-07-30T00:00:00Z"), -// mustParseRFC3339("2021-08-30T00:00:00Z"), +// types.ParseTime("2021-07-30T00:00:00Z"), +// types.ParseTime("2021-08-30T00:00:00Z"), // ), // sdk.NewCoins(sdk.NewInt64Coin(denom3, 1_000_000))), // } @@ -55,8 +55,8 @@ package keeper_test // sdk.NewDecCoins( // sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1))), -// mustParseRFC3339("2021-07-30T00:00:00Z"), -// mustParseRFC3339("2021-08-30T00:00:00Z"), +// types.ParseTime("2021-07-30T00:00:00Z"), +// types.ParseTime("2021-08-30T00:00:00Z"), // ), // sdk.NewCoins(sdk.NewInt64Coin(denom3, 1_000_000))), // } @@ -70,7 +70,7 @@ package keeper_test // // suite.keeper.ProcessQueuedCoins(suite.ctx) // -// suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-07-31T00:00:00Z")) +// suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-07-31T00:00:00Z")) // err := suite.keeper.AllocateRewards(suite.ctx) // suite.Require().NoError(err) // diff --git a/x/farming/keeper/keeper_test.go b/x/farming/keeper/keeper_test.go index 6e057fb4..b4434f8c 100644 --- a/x/farming/keeper/keeper_test.go +++ b/x/farming/keeper/keeper_test.go @@ -2,7 +2,6 @@ package keeper_test import ( "testing" - "time" "github.com/stretchr/testify/suite" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -70,8 +69,8 @@ func (suite *KeeperTestSuite) SetupTest() { sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% ), - mustParseRFC3339("2021-08-02T00:00:00Z"), - mustParseRFC3339("2021-08-10T00:00:00Z"), + types.ParseTime("2021-08-02T00:00:00Z"), + types.ParseTime("2021-08-10T00:00:00Z"), ), sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000000)), ), @@ -85,8 +84,8 @@ func (suite *KeeperTestSuite) SetupTest() { sdk.NewDecCoins( sdk.NewDecCoinFromDec(denom1, sdk.OneDec()), // 100% ), - mustParseRFC3339("2021-08-04T00:00:00Z"), - mustParseRFC3339("2021-08-12T00:00:00Z"), + types.ParseTime("2021-08-04T00:00:00Z"), + types.ParseTime("2021-08-12T00:00:00Z"), ), sdk.NewCoins(sdk.NewInt64Coin(denom3, 2000000)), ), @@ -103,8 +102,8 @@ func (suite *KeeperTestSuite) SetupTest() { sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(5, 1)), // 50% sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(5, 1)), // 50% ), - mustParseRFC3339("2021-08-01T00:00:00Z"), - mustParseRFC3339("2021-08-09T00:00:00Z"), + types.ParseTime("2021-08-01T00:00:00Z"), + types.ParseTime("2021-08-09T00:00:00Z"), ), sdk.NewDecWithPrec(4, 2), // 4% ), @@ -118,8 +117,8 @@ func (suite *KeeperTestSuite) SetupTest() { sdk.NewDecCoins( sdk.NewDecCoinFromDec(denom2, sdk.OneDec()), // 100% ), - mustParseRFC3339("2021-08-03T00:00:00Z"), - mustParseRFC3339("2021-08-07T00:00:00Z"), + types.ParseTime("2021-08-03T00:00:00Z"), + types.ParseTime("2021-08-07T00:00:00Z"), ), sdk.NewDecWithPrec(3, 2), // 3% ), @@ -147,11 +146,3 @@ func intEq(exp, got sdk.Int) (bool, string, string, string) { func coinsEq(exp, got sdk.Coins) (bool, string, string, string) { return exp.IsEqual(got), "expected:\t%v\ngot:\t\t%v", exp.String(), got.String() } - -func mustParseRFC3339(s string) time.Time { - t, err := time.Parse(time.RFC3339, s) - if err != nil { - panic(err) - } - return t -} diff --git a/x/farming/keeper/proposal_handler_test.go b/x/farming/keeper/proposal_handler_test.go index 67766257..ed17111b 100644 --- a/x/farming/keeper/proposal_handler_test.go +++ b/x/farming/keeper/proposal_handler_test.go @@ -29,8 +29,8 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { FarmingPoolAddress: farmerAddr.String(), TerminationAddress: terminationAddr.String(), StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("2021-08-06T00:00:00Z"), - EndTime: mustParseRFC3339("2021-08-13T00:00:00Z"), + 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(), } @@ -45,8 +45,8 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { FarmingPoolAddress: farmerAddr.String(), TerminationAddress: terminationAddr.String(), StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("2021-08-06T00:00:00Z"), - EndTime: mustParseRFC3339("2021-08-13T00:00:00Z"), + 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(), } @@ -58,8 +58,8 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { FarmingPoolAddress: farmerAddr.String(), TerminationAddress: terminationAddr.String(), StakingCoinWeights: sdk.NewDecCoins(), - StartTime: mustParseRFC3339("2021-08-06T00:00:00Z"), - EndTime: mustParseRFC3339("2021-08-13T00:00:00Z"), + 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(), } @@ -76,8 +76,8 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { Amount: sdk.MustNewDecFromStr("0.1"), }, ), - StartTime: mustParseRFC3339("2021-08-06T00:00:00Z"), - EndTime: mustParseRFC3339("2021-08-13T00:00:00Z"), + 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(), } @@ -89,8 +89,8 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { FarmingPoolAddress: farmerAddr.String(), TerminationAddress: terminationAddr.String(), StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("2021-08-13T00:00:00Z"), - EndTime: mustParseRFC3339("2021-08-06T00:00:00Z"), + 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(), } @@ -102,8 +102,8 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { FarmingPoolAddress: farmerAddr.String(), TerminationAddress: terminationAddr.String(), StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("2021-08-06T00:00:00Z"), - EndTime: mustParseRFC3339("2021-08-13T00:00:00Z"), + 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), } @@ -115,8 +115,8 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { FarmingPoolAddress: farmerAddr.String(), TerminationAddress: terminationAddr.String(), StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("2021-08-06T00:00:00Z"), - EndTime: mustParseRFC3339("2021-08-13T00:00:00Z"), + StartTime: types.ParseTime("2021-08-06T00:00:00Z"), + EndTime: types.ParseTime("2021-08-13T00:00:00Z"), EpochAmount: sdk.NewCoins(), EpochRatio: sdk.ZeroDec(), } @@ -162,7 +162,7 @@ func (suite *KeeperTestSuite) TestAddPublicPlanProposal() { case5, sdkerrors.Wrapf(types.ErrInvalidPlanEndTime, "end time %s must be greater than start time %s", - mustParseRFC3339("2021-08-06T00:00:00Z"), mustParseRFC3339("2021-08-13T00:00:00Z")), + types.ParseTime("2021-08-06T00:00:00Z"), types.ParseTime("2021-08-13T00:00:00Z")), }, { "epoch amount & epoch ratio case #1", @@ -217,8 +217,8 @@ func (suite *KeeperTestSuite) TestUpdatePublicPlanProposal() { FarmingPoolAddress: farmerAddr.String(), TerminationAddress: terminationAddr.String(), StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("2021-08-06T00:00:00Z"), - EndTime: mustParseRFC3339("2021-08-13T00:00:00Z"), + 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(), } @@ -242,8 +242,8 @@ func (suite *KeeperTestSuite) TestUpdatePublicPlanProposal() { suite.Require().Equal(true, found) // case1 - startTime := mustParseRFC3339("2021-08-06T00:00:00Z") - endTime := mustParseRFC3339("2021-08-13T00:00:00Z") + startTime := types.ParseTime("2021-08-06T00:00:00Z") + endTime := types.ParseTime("2021-08-13T00:00:00Z") req := &types.UpdateRequestProposal{ PlanId: uint64(1), @@ -409,7 +409,7 @@ func (suite *KeeperTestSuite) TestUpdatePublicPlanProposal() { case6, sdkerrors.Wrapf(types.ErrInvalidPlanEndTime, "end time %s must be greater than start time %s", - mustParseRFC3339("2021-08-06T00:00:00Z"), mustParseRFC3339("2021-08-13T00:00:00Z")), + types.ParseTime("2021-08-06T00:00:00Z"), types.ParseTime("2021-08-13T00:00:00Z")), }, { "epoch amount & epoch ratio case #1", @@ -463,8 +463,8 @@ func (suite *KeeperTestSuite) TestDeletePublicPlanProposal() { FarmingPoolAddress: farmerAddr.String(), TerminationAddress: terminationAddr.String(), StakingCoinWeights: coinWeights, - StartTime: mustParseRFC3339("2021-08-06T00:00:00Z"), - EndTime: mustParseRFC3339("2021-08-13T00:00:00Z"), + 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(), } diff --git a/x/farming/keeper/reward_test.go b/x/farming/keeper/reward_test.go index 18eeda14..819bce57 100644 --- a/x/farming/keeper/reward_test.go +++ b/x/farming/keeper/reward_test.go @@ -20,8 +20,8 @@ func (suite *KeeperTestSuite) TestAllocationInfos() { suite.addrs[0].String(), suite.addrs[0].String(), sdk.NewDecCoins(sdk.NewDecCoinFromDec(denom1, sdk.NewDec(1))), - mustParseRFC3339("2021-07-27T00:00:00Z"), - mustParseRFC3339("2021-07-28T00:00:00Z"), + types.ParseTime("2021-07-27T00:00:00Z"), + types.ParseTime("2021-07-28T00:00:00Z"), ), sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000))), types.NewFixedAmountPlan( @@ -32,8 +32,8 @@ func (suite *KeeperTestSuite) TestAllocationInfos() { suite.addrs[0].String(), suite.addrs[0].String(), sdk.NewDecCoins(sdk.NewDecCoinFromDec(denom1, sdk.NewDec(1))), - mustParseRFC3339("2021-07-27T12:00:00Z"), - mustParseRFC3339("2021-07-28T12:00:00Z"), + types.ParseTime("2021-07-27T12:00:00Z"), + types.ParseTime("2021-07-28T12:00:00Z"), ), sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000))), } @@ -55,36 +55,36 @@ func (suite *KeeperTestSuite) TestAllocationInfos() { suite.addrs[0].String(), suite.addrs[0].String(), sdk.NewDecCoins(sdk.NewDecCoinFromDec(denom1, sdk.NewDec(1))), - mustParseRFC3339("2021-07-27T00:00:00Z"), - mustParseRFC3339("2021-07-30T00:00:00Z"), + types.ParseTime("2021-07-27T00:00:00Z"), + types.ParseTime("2021-07-30T00:00:00Z"), ), sdk.NewCoins(sdk.NewInt64Coin(denom3, 10_000_000_000))), }, - mustParseRFC3339("2021-07-28T00:00:00Z"), + types.ParseTime("2021-07-28T00:00:00Z"), nil, }, { "start time & end time edgecase #1", normalPlans, - mustParseRFC3339("2021-07-26T23:59:59Z"), + types.ParseTime("2021-07-26T23:59:59Z"), nil, }, { "start time & end time edgecase #2", normalPlans, - mustParseRFC3339("2021-07-27T00:00:00Z"), + types.ParseTime("2021-07-27T00:00:00Z"), map[uint64]sdk.Coins{1: sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000))}, }, { "start time & end time edgecase #3", normalPlans, - mustParseRFC3339("2021-07-27T11:59:59Z"), + types.ParseTime("2021-07-27T11:59:59Z"), map[uint64]sdk.Coins{1: sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000))}, }, { "start time & end time edgecase #4", normalPlans, - mustParseRFC3339("2021-07-27T12:00:00Z"), + types.ParseTime("2021-07-27T12:00:00Z"), map[uint64]sdk.Coins{ 1: sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000)), 2: sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000))}, @@ -92,7 +92,7 @@ func (suite *KeeperTestSuite) TestAllocationInfos() { { "start time & end time edgecase #5", normalPlans, - mustParseRFC3339("2021-07-27T23:59:59Z"), + types.ParseTime("2021-07-27T23:59:59Z"), map[uint64]sdk.Coins{ 1: sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000)), 2: sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000))}, @@ -100,19 +100,19 @@ func (suite *KeeperTestSuite) TestAllocationInfos() { { "start time & end time edgecase #6", normalPlans, - mustParseRFC3339("2021-07-28T00:00:00Z"), + types.ParseTime("2021-07-28T00:00:00Z"), map[uint64]sdk.Coins{2: sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000))}, }, { "start time & end time edgecase #7", normalPlans, - mustParseRFC3339("2021-07-28T11:59:59Z"), + types.ParseTime("2021-07-28T11:59:59Z"), map[uint64]sdk.Coins{2: sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000))}, }, { "start time & end time edgecase #8", normalPlans, - mustParseRFC3339("2021-07-28T12:00:00Z"), + types.ParseTime("2021-07-28T12:00:00Z"), nil, }, } { @@ -137,8 +137,8 @@ func (suite *KeeperTestSuite) TestAllocationInfos() { func (suite *KeeperTestSuite) TestAllocateRewards() { for _, plan := range suite.sampleFixedAmtPlans { - _ = plan.SetStartTime(mustParseRFC3339("0001-01-01T00:00:00Z")) - _ = plan.SetEndTime(mustParseRFC3339("9999-12-31T00:00:00Z")) + _ = plan.SetStartTime(types.ParseTime("0001-01-01T00:00:00Z")) + _ = plan.SetEndTime(types.ParseTime("9999-12-31T00:00:00Z")) suite.keeper.SetPlan(suite.ctx, plan) } @@ -148,7 +148,7 @@ func (suite *KeeperTestSuite) TestAllocateRewards() { prevDistrCoins := map[uint64]sdk.Coins{} - t := mustParseRFC3339("2021-09-01T00:00:00Z") + t := types.ParseTime("2021-09-01T00:00:00Z") for i := 0; i < 365; i++ { suite.ctx = suite.ctx.WithBlockTime(t) @@ -181,7 +181,7 @@ func (suite *KeeperTestSuite) TestHarvest() { suite.keeper.ProcessQueuedCoins(suite.ctx) balancesBefore := suite.app.BankKeeper.GetAllBalances(suite.ctx, suite.addrs[0]) - suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-08-05T00:00:00Z")) + suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-08-05T00:00:00Z")) err := suite.keeper.AllocateRewards(suite.ctx) suite.Require().NoError(err) diff --git a/x/farming/keeper/simulation_test.go b/x/farming/keeper/simulation_test.go index 1a828777..853eeb7e 100644 --- a/x/farming/keeper/simulation_test.go +++ b/x/farming/keeper/simulation_test.go @@ -80,7 +80,7 @@ func (tra TotalRewardsAssertion) Do(suite *KeeperTestSuite) { } func (suite *KeeperTestSuite) TestSimulation() { - suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-09-01T00:00:00Z")) + suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-09-01T00:00:00Z")) for _, plan := range []types.PlanI{ types.NewFixedAmountPlan( @@ -94,8 +94,8 @@ func (suite *KeeperTestSuite) TestSimulation() { sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% ), - mustParseRFC3339("0001-01-01T00:00:00Z"), - mustParseRFC3339("9999-12-31T00:00:00Z"), + types.ParseTime("0001-01-01T00:00:00Z"), + types.ParseTime("9999-12-31T00:00:00Z"), ), sdk.NewCoins(sdk.NewInt64Coin(denom3, 1000000)), ), diff --git a/x/farming/module_test.go b/x/farming/module_test.go index e4c156b6..638b6d94 100644 --- a/x/farming/module_test.go +++ b/x/farming/module_test.go @@ -2,7 +2,6 @@ package farming_test import ( "testing" - "time" "github.com/stretchr/testify/suite" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -70,8 +69,8 @@ func (suite *ModuleTestSuite) SetupTest() { sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(3, 1)), // 30% sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(7, 1)), // 70% ), - mustParseRFC3339("2021-08-02T00:00:00Z"), - mustParseRFC3339("2021-08-10T00:00:00Z"), + types.ParseTime("2021-08-02T00:00:00Z"), + types.ParseTime("2021-09-02T00:00:00Z"), ), sdk.NewCoins(sdk.NewInt64Coin(denom3, 1_000_000)), ), @@ -85,8 +84,8 @@ func (suite *ModuleTestSuite) SetupTest() { sdk.NewDecCoins( sdk.NewDecCoinFromDec(denom1, sdk.OneDec()), // 100% ), - mustParseRFC3339("2021-08-04T00:00:00Z"), - mustParseRFC3339("2021-08-12T00:00:00Z"), + types.ParseTime("2021-08-04T00:00:00Z"), + types.ParseTime("2021-08-12T00:00:00Z"), ), sdk.NewCoins(sdk.NewInt64Coin(denom3, 2_000_000)), ), @@ -103,8 +102,8 @@ func (suite *ModuleTestSuite) SetupTest() { sdk.NewDecCoinFromDec(denom1, sdk.NewDecWithPrec(5, 1)), // 50% sdk.NewDecCoinFromDec(denom2, sdk.NewDecWithPrec(5, 1)), // 50% ), - mustParseRFC3339("2021-08-01T00:00:00Z"), - mustParseRFC3339("2021-08-09T00:00:00Z"), + types.ParseTime("2021-08-01T00:00:00Z"), + types.ParseTime("2021-08-09T00:00:00Z"), ), sdk.NewDecWithPrec(4, 2), // 4% ), @@ -118,8 +117,8 @@ func (suite *ModuleTestSuite) SetupTest() { sdk.NewDecCoins( sdk.NewDecCoinFromDec(denom2, sdk.OneDec()), // 100% ), - mustParseRFC3339("2021-08-03T00:00:00Z"), - mustParseRFC3339("2021-08-07T00:00:00Z"), + types.ParseTime("2021-08-03T00:00:00Z"), + types.ParseTime("2021-08-07T00:00:00Z"), ), sdk.NewDecWithPrec(3, 2), // 3% ), @@ -144,11 +143,3 @@ func (suite *ModuleTestSuite) Rewards(farmerAcc sdk.AccAddress) sdk.Coins { func coinsEq(exp, got sdk.Coins) (bool, string, string, string) { return exp.IsEqual(got), "expected:\t%v\ngot:\t\t%v", exp.String(), got.String() } - -func mustParseRFC3339(s string) time.Time { - t, err := time.Parse(time.RFC3339, s) - if err != nil { - panic(err) - } - return t -} diff --git a/x/farming/simulation/operations_test.go b/x/farming/simulation/operations_test.go index 7258322d..40184c19 100644 --- a/x/farming/simulation/operations_test.go +++ b/x/farming/simulation/operations_test.go @@ -3,7 +3,6 @@ package simulation_test import ( "math/rand" "testing" - "time" "github.com/stretchr/testify/require" @@ -232,8 +231,8 @@ func TestSimulateMsgHarvest(t *testing.T) { StakingCoinWeights: sdk.NewDecCoins( sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, sdk.NewDecWithPrec(10, 1)), // 100% ), - StartTime: mustParseRFC3339("0001-01-01T00:00:00Z"), - EndTime: mustParseRFC3339("9999-01-01T00:00:00Z"), + StartTime: types.ParseTime("0001-01-01T00:00:00Z"), + EndTime: types.ParseTime("9999-01-01T00:00:00Z"), EpochAmount: sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 200_000_000)), } @@ -317,11 +316,3 @@ func getTestingAccounts(t *testing.T, r *rand.Rand, app *farmingapp.FarmingApp, return accounts } - -func mustParseRFC3339(s string) time.Time { - t, err := time.Parse(time.RFC3339, s) - if err != nil { - panic(err) - } - return t -} diff --git a/x/farming/simulation/proposals_test.go b/x/farming/simulation/proposals_test.go index 33ac035b..059eb55c 100644 --- a/x/farming/simulation/proposals_test.go +++ b/x/farming/simulation/proposals_test.go @@ -55,8 +55,8 @@ func TestProposalContents(t *testing.T) { StakingCoinWeights: sdk.NewDecCoins( sdk.NewDecCoinFromDec(sdk.DefaultBondDenom, sdk.NewDecWithPrec(10, 1)), // 100% ), - StartTime: mustParseRFC3339("2021-08-01T00:00:00Z"), - EndTime: mustParseRFC3339("2021-08-31T00:00:00Z"), + StartTime: types.ParseTime("2021-08-01T00:00:00Z"), + EndTime: types.ParseTime("2021-08-31T00:00:00Z"), EpochAmount: sdk.NewCoins(sdk.NewInt64Coin(sdk.DefaultBondDenom, 200_000_000)), } diff --git a/x/farming/types/plan_test.go b/x/farming/types/plan_test.go index e6681c16..04d4e6fa 100644 --- a/x/farming/types/plan_test.go +++ b/x/farming/types/plan_test.go @@ -134,8 +134,8 @@ func TestUnpackPlan(t *testing.T) { types.PrivatePlanFarmingPoolAddress("farmingPoolAddr1", 1).String(), sdk.AccAddress("terminationAddr1").String(), sdk.NewDecCoins(sdk.DecCoin{Denom: "testFarmStakingCoinDenom", Amount: sdk.MustNewDecFromStr("1.0")}), - mustParseRFC3339("2021-08-03T00:00:00Z"), - mustParseRFC3339("2021-08-07T00:00:00Z"), + types.ParseTime("2021-08-03T00:00:00Z"), + types.ParseTime("2021-08-07T00:00:00Z"), ), sdk.NewDec(1), ), @@ -163,11 +163,3 @@ func TestUnpackPlan(t *testing.T) { _, err = types.UnpackPlan(&planRecord.Plan) require.NoError(t, err) } - -func mustParseRFC3339(s string) time.Time { - t, err := time.Parse(time.RFC3339, s) - if err != nil { - panic(err) - } - return t -} diff --git a/x/farming/types/utils.go b/x/farming/types/utils.go new file mode 100644 index 00000000..ff9ddb23 --- /dev/null +++ b/x/farming/types/utils.go @@ -0,0 +1,12 @@ +package types + +import time "time" + +// ParseTime parses string time to time in RFC3339 format. +func ParseTime(s string) time.Time { + t, err := time.Parse(time.RFC3339, s) + if err != nil { + panic(err) + } + return t +} From 9cc402b8a6a58b5dfa5239b796d50066acdb6b7a Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 15 Sep 2021 19:29:07 +0900 Subject: [PATCH 12/20] docs: update spec docs --- x/farming/spec/03_state_transitions.md | 4 ++-- x/farming/spec/08_params.md | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x/farming/spec/03_state_transitions.md b/x/farming/spec/03_state_transitions.md index 9eaf837b..1d5db5d1 100644 --- a/x/farming/spec/03_state_transitions.md +++ b/x/farming/spec/03_state_transitions.md @@ -31,10 +31,10 @@ const ( - Each `farmingPlan` has its own `startTime` and `endTime` - Distribution Method - `FixedAmountPlan` - - fixed amount of coins are distributed for each `epochDays` + - fixed amount of coins are distributed for each `NextEpochDays` - amount in `sdk.Coins` - `RatioPlan` - - `epochRatio` of total assets in `farmingPoolAddress` is distributed for each `epochDays` + - `epochRatio` of total assets in `farmingPoolAddress` is distributed for each `NextEpochDays` - `epochRatio` in percentage - Termination Address - When the plan ends after the `endTime`, transfer the balance of `farmingPoolAddress` to `terminationAddress`. diff --git a/x/farming/spec/08_params.md b/x/farming/spec/08_params.md index e6fcf4e1..2e874b5d 100644 --- a/x/farming/spec/08_params.md +++ b/x/farming/spec/08_params.md @@ -7,16 +7,16 @@ The farming module contains the following parameters: | Key | Type | Example | | -------------------------- | --------- | ------------------------------------------------------------------- | | PrivatePlanCreationFee | sdk.Coins | [{"denom":"stake","amount":"100000000"}] | -| EpochDays | uint32 | 1 | +| NextEpochDays | uint32 | 1 | | FarmingFeeCollector | string | "cosmos1h292smhhttwy0rl3qr4p6xsvpvxc4v05s6rxtczwq3cs6qc462mqejwy8x" | ## PrivatePlanCreationFee Fee paid for to create a Private type Farming plan. This fee prevents spamming and is collected in in the community pool of the distribution module. -## EpochDays +## NextEpochDays -The universal epoch length in number of days. Every process for staking and reward distribution is executed with this `EpochDays` frequency. +`NextEpochDays` is the epoch length in number of days. Internally, the farming module uses `GlobalCurrentEpochDays` to process staking and reward distribution in end blocker because using `NextEpochDays` directly will affect farming rewards allocation. ## FarmingFeeCollector From 793bfe1e9ac0c57113c67d916831169b4ba656f9 Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 15 Sep 2021 19:37:34 +0900 Subject: [PATCH 13/20] feat: adding test for end blocker --- x/farming/abci.go | 8 +++++--- x/farming/abci_test.go | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/x/farming/abci.go b/x/farming/abci.go index a79c97f9..e1ac926b 100644 --- a/x/farming/abci.go +++ b/x/farming/abci.go @@ -21,9 +21,11 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) { } } - // GlobalCurrentEpochDays is used here to proceed the next logics instead of - // global parameter NextEpochDays to prevent from affecting the epoch days when allocating farming rewards - // NextEpochDays can be changed through governance proposal during the allocation + // GlobalCurrentEpochDays is used here instead of global parameter NextEpochDays + // to prevent from affecting the epoch days for farming rewards allocation. + // Suppose NextEpochDays is 7 days now and it is proposed to change it to 1 day through governance proposal. + // Although the proposal is passed, farming rewards allocation must continue + // to proceed with 7 days first and then it gets updated. currentEpochDays := k.GetGlobalCurrentEpochDays(ctx) lastEpochTime, found := k.GetLastEpochTime(ctx) diff --git a/x/farming/abci_test.go b/x/farming/abci_test.go index 6b8e6376..666ca04d 100644 --- a/x/farming/abci_test.go +++ b/x/farming/abci_test.go @@ -1,17 +1,47 @@ package farming_test import ( + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/farming/x/farming" + "github.com/tendermint/farming/x/farming/types" _ "github.com/stretchr/testify/suite" ) func (suite *ModuleTestSuite) TestEndBlocker() { + // set NextEpochDays and GlobalCurrentEpochDays to 7 days params := suite.keeper.GetParams(suite.ctx) - suite.Require().Equal(uint32(1), params.NextEpochDays) + params.NextEpochDays = 7 + suite.keeper.SetParams(suite.ctx, params) + suite.keeper.SetGlobalCurrentEpochDays(suite.ctx, params.NextEpochDays) + + // set fixed amount plan + suite.keeper.SetPlan(suite.ctx, suite.sampleFixedAmtPlans[0]) + + suite.Stake(suite.addrs[0], sdk.NewCoins(sdk.NewInt64Coin(denom2, 10_000_000))) + suite.keeper.ProcessQueuedCoins(suite.ctx) + + currEpochDays := suite.keeper.GetGlobalCurrentEpochDays(suite.ctx) + fmt.Println("currEpochDays: ", currEpochDays) - suite.ctx = suite.ctx.WithBlockTime(mustParseRFC3339("2021-08-11T23:59:59Z")) + balancesBefore := suite.app.BankKeeper.GetAllBalances(suite.ctx, suite.addrs[0]) + fmt.Println("balancesBefore: ", balancesBefore) + + suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-08-05T00:00:00Z")) farming.EndBlocker(suite.ctx, suite.keeper) - // WIP + balancesAfter := suite.app.BankKeeper.GetAllBalances(suite.ctx, suite.addrs[0]) + fmt.Println("balancesAfter: ", balancesAfter) + + farming.EndBlocker(suite.ctx, suite.keeper) + + // suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-08-11T23:59:59Z")) + // farming.EndBlocker(suite.ctx, suite.keeper) + + // + // params.NextEpochDays = 1 + // suite.keeper.SetParams(suite.ctx, params) } From 15a4d453c937b3dbc938d1a79f7fab7d52ab6549 Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 15 Sep 2021 22:04:02 +0900 Subject: [PATCH 14/20] chore: rename GlobalCurrentEpochDays to CurrentEpochDays and refactor codes --- .../tendermint/farming/v1beta1/farming.proto | 2 +- x/farming/abci.go | 19 ++--- x/farming/abci_test.go | 85 +++++++++++++------ x/farming/keeper/epoch.go | 12 +-- x/farming/keeper/epoch_test.go | 9 +- x/farming/keeper/genesis.go | 2 +- x/farming/spec/08_params.md | 2 +- x/farming/types/farming.pb.go | 2 +- x/farming/types/keys.go | 6 +- 9 files changed, 87 insertions(+), 52 deletions(-) diff --git a/proto/tendermint/farming/v1beta1/farming.proto b/proto/tendermint/farming/v1beta1/farming.proto index e7d39129..dd335a75 100644 --- a/proto/tendermint/farming/v1beta1/farming.proto +++ b/proto/tendermint/farming/v1beta1/farming.proto @@ -23,7 +23,7 @@ message Params { ]; // next_epoch_days is the epoch length in number of days - // it updates internal parameter called GlobalCurrentEpochDays that is used to process + // it updates internal parameter called CurrentEpochDays that is used to process // staking and reward distribution in end blocker uint32 next_epoch_days = 2 [(gogoproto.moretags) = "yaml:\"next_epoch_days\""]; diff --git a/x/farming/abci.go b/x/farming/abci.go index e1ac926b..ecedab4f 100644 --- a/x/farming/abci.go +++ b/x/farming/abci.go @@ -21,12 +21,11 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) { } } - // GlobalCurrentEpochDays is used here instead of global parameter NextEpochDays - // to prevent from affecting the epoch days for farming rewards allocation. - // Suppose NextEpochDays is 7 days now and it is proposed to change it to 1 day through governance proposal. - // Although the proposal is passed, farming rewards allocation must continue - // to proceed with 7 days first and then it gets updated. - currentEpochDays := k.GetGlobalCurrentEpochDays(ctx) + // CurrentEpochDays is intialized with the value of NextEpochDays in genesis and + // it is used here to prevent from affecting the epoch days for farming rewards allocation. + // Suppose NextEpochDays is 7 days and it is proposed to change the value to 1 day through governance proposal. + // Although the proposal is passed, farming rewards allocation should continue to proceed with 7 days and then it gets updated. + currentEpochDays := k.GetCurrentEpochDays(ctx) lastEpochTime, found := k.GetLastEpochTime(ctx) if !found { @@ -38,11 +37,9 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) { if err := k.AdvanceEpoch(ctx); err != nil { panic(err) } + if params := k.GetParams(ctx); params.NextEpochDays != currentEpochDays { + k.SetCurrentEpochDays(ctx, params.NextEpochDays) + } } } - - params := k.GetParams(ctx) - if params.NextEpochDays != currentEpochDays { - k.SetGlobalCurrentEpochDays(ctx, params.NextEpochDays) - } } diff --git a/x/farming/abci_test.go b/x/farming/abci_test.go index 666ca04d..bb094fc0 100644 --- a/x/farming/abci_test.go +++ b/x/farming/abci_test.go @@ -1,9 +1,7 @@ package farming_test import ( - "fmt" - - sdk "github.com/cosmos/cosmos-sdk/types" + "time" "github.com/tendermint/farming/x/farming" "github.com/tendermint/farming/x/farming/types" @@ -11,37 +9,76 @@ import ( _ "github.com/stretchr/testify/suite" ) -func (suite *ModuleTestSuite) TestEndBlocker() { - // set NextEpochDays and GlobalCurrentEpochDays to 7 days +func (suite *ModuleTestSuite) TestEndBlockerEdgeCase1() { + suite.SetupTest() + + nextEpochDays := uint32(7) + params := suite.keeper.GetParams(suite.ctx) - params.NextEpochDays = 7 + params.NextEpochDays = nextEpochDays suite.keeper.SetParams(suite.ctx, params) - suite.keeper.SetGlobalCurrentEpochDays(suite.ctx, params.NextEpochDays) + suite.keeper.SetCurrentEpochDays(suite.ctx, params.NextEpochDays) - // set fixed amount plan - suite.keeper.SetPlan(suite.ctx, suite.sampleFixedAmtPlans[0]) + t := types.ParseTime("2021-08-01T00:00:00Z") + suite.ctx = suite.ctx.WithBlockTime(t) + farming.EndBlocker(suite.ctx, suite.keeper) - suite.Stake(suite.addrs[0], sdk.NewCoins(sdk.NewInt64Coin(denom2, 10_000_000))) - suite.keeper.ProcessQueuedCoins(suite.ctx) + lastEpochTime, _ := suite.keeper.GetLastEpochTime(suite.ctx) - currEpochDays := suite.keeper.GetGlobalCurrentEpochDays(suite.ctx) - fmt.Println("currEpochDays: ", currEpochDays) + for i := 1; i < 200; i++ { + t = t.Add(1 * time.Hour) + suite.ctx = suite.ctx.WithBlockTime(t) + farming.EndBlocker(suite.ctx, suite.keeper) - balancesBefore := suite.app.BankKeeper.GetAllBalances(suite.ctx, suite.addrs[0]) - fmt.Println("balancesBefore: ", balancesBefore) + if i == 120 { // 5 days passed + params := suite.keeper.GetParams(suite.ctx) + params.NextEpochDays = uint32(1) + suite.keeper.SetParams(suite.ctx, params) + } - suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-08-05T00:00:00Z")) - farming.EndBlocker(suite.ctx, suite.keeper) + currentEpochDays := suite.keeper.GetCurrentEpochDays(suite.ctx) + + t2, _ := suite.keeper.GetLastEpochTime(suite.ctx) + if t2.After(lastEpochTime) { + suite.Require().GreaterOrEqual(t2.Sub(lastEpochTime).Hours(), float64(nextEpochDays*24)) + suite.Require().Equal(uint32(1), currentEpochDays) + } + } +} - balancesAfter := suite.app.BankKeeper.GetAllBalances(suite.ctx, suite.addrs[0]) - fmt.Println("balancesAfter: ", balancesAfter) +func (suite *ModuleTestSuite) TestEndBlockerEdgeCase2() { + suite.SetupTest() + nextEpochDays := uint32(1) + + params := suite.keeper.GetParams(suite.ctx) + params.NextEpochDays = nextEpochDays + suite.keeper.SetParams(suite.ctx, params) + suite.keeper.SetCurrentEpochDays(suite.ctx, params.NextEpochDays) + + t := types.ParseTime("2021-08-01T00:00:00Z") + suite.ctx = suite.ctx.WithBlockTime(t) farming.EndBlocker(suite.ctx, suite.keeper) - // suite.ctx = suite.ctx.WithBlockTime(types.ParseTime("2021-08-11T23:59:59Z")) - // farming.EndBlocker(suite.ctx, suite.keeper) + lastEpochTime, _ := suite.keeper.GetLastEpochTime(suite.ctx) + + for i := 1; i < 50; i++ { + t = t.Add(1 * time.Hour) + suite.ctx = suite.ctx.WithBlockTime(t) + farming.EndBlocker(suite.ctx, suite.keeper) + + if i == 10 { // 10 hours passed + params := suite.keeper.GetParams(suite.ctx) + params.NextEpochDays = uint32(7) + suite.keeper.SetParams(suite.ctx, params) + } + + currentEpochDays := suite.keeper.GetCurrentEpochDays(suite.ctx) - // - // params.NextEpochDays = 1 - // suite.keeper.SetParams(suite.ctx, params) + t2, _ := suite.keeper.GetLastEpochTime(suite.ctx) + if t2.After(lastEpochTime) { + suite.Require().GreaterOrEqual(t2.Sub(lastEpochTime).Hours(), float64(nextEpochDays*24)) + suite.Require().Equal(uint32(7), currentEpochDays) + } + } } diff --git a/x/farming/keeper/epoch.go b/x/farming/keeper/epoch.go index f9f6fd28..bfd3a17e 100644 --- a/x/farming/keeper/epoch.go +++ b/x/farming/keeper/epoch.go @@ -45,11 +45,11 @@ func (k Keeper) AdvanceEpoch(ctx sdk.Context) error { return nil } -// GetGlobalCurrentEpochDays returns the global current epoch days. -func (k Keeper) GetGlobalCurrentEpochDays(ctx sdk.Context) uint32 { +// GetCurrentEpochDays returns the current epoch days. +func (k Keeper) GetCurrentEpochDays(ctx sdk.Context) uint32 { var epochDays uint32 store := ctx.KVStore(k.storeKey) - bz := store.Get(types.GlobalCurrentEpochDaysKey) + bz := store.Get(types.CurrentEpochDaysKey) if bz == nil { // initialize the current epoch days epochDays = 1 @@ -63,9 +63,9 @@ func (k Keeper) GetGlobalCurrentEpochDays(ctx sdk.Context) uint32 { return epochDays } -// SetGlobalCurrentEpochDays sets the global current epoch days. -func (k Keeper) SetGlobalCurrentEpochDays(ctx sdk.Context, epochDays uint32) { +// SetCurrentEpochDays sets the current epoch days. +func (k Keeper) SetCurrentEpochDays(ctx sdk.Context, epochDays uint32) { store := ctx.KVStore(k.storeKey) bz := k.cdc.MustMarshal(&gogotypes.UInt32Value{Value: epochDays}) - store.Set(types.GlobalCurrentEpochDaysKey, bz) + store.Set(types.CurrentEpochDaysKey, bz) } diff --git a/x/farming/keeper/epoch_test.go b/x/farming/keeper/epoch_test.go index 384b0502..2d9d5b72 100644 --- a/x/farming/keeper/epoch_test.go +++ b/x/farming/keeper/epoch_test.go @@ -43,12 +43,12 @@ func (suite *KeeperTestSuite) TestFirstEpoch() { } func (suite *KeeperTestSuite) TestEpochDays() { - for _, epochDays := range []uint32{1, 2, 3} { - suite.Run(fmt.Sprintf("epoch days = %d", epochDays), func() { + for _, nextEpochDays := range []uint32{1, 2, 3} { + suite.Run(fmt.Sprintf("next epoch days = %d", nextEpochDays), func() { suite.SetupTest() params := suite.keeper.GetParams(suite.ctx) - params.NextEpochDays = epochDays + params.NextEpochDays = nextEpochDays suite.keeper.SetParams(suite.ctx, params) t := types.ParseTime("2021-08-11T00:00:00Z") @@ -56,6 +56,7 @@ func (suite *KeeperTestSuite) TestEpochDays() { farming.EndBlocker(suite.ctx, suite.keeper) lastEpochTime, _ := suite.keeper.GetLastEpochTime(suite.ctx) + currentEpochDays := suite.keeper.GetCurrentEpochDays(suite.ctx) for i := 0; i < 10000; i++ { t = t.Add(5 * time.Minute) @@ -64,7 +65,7 @@ func (suite *KeeperTestSuite) TestEpochDays() { t2, _ := suite.keeper.GetLastEpochTime(suite.ctx) if t2.After(lastEpochTime) { - suite.Require().GreaterOrEqual(t2.Sub(lastEpochTime).Hours(), float64(epochDays*24)) + suite.Require().GreaterOrEqual(t2.Sub(lastEpochTime).Hours(), float64(currentEpochDays*24)) lastEpochTime = t2 } } diff --git a/x/farming/keeper/genesis.go b/x/farming/keeper/genesis.go index d37a4d38..f078e9cd 100644 --- a/x/farming/keeper/genesis.go +++ b/x/farming/keeper/genesis.go @@ -11,7 +11,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) { ctx, applyCache := ctx.CacheContext() k.SetParams(ctx, genState.Params) - k.SetGlobalCurrentEpochDays(ctx, genState.Params.NextEpochDays) + k.SetCurrentEpochDays(ctx, genState.Params.NextEpochDays) moduleAcc := k.accountKeeper.GetModuleAccount(ctx, types.ModuleName) k.accountKeeper.SetModuleAccount(ctx, moduleAcc) diff --git a/x/farming/spec/08_params.md b/x/farming/spec/08_params.md index 2e874b5d..c53bf770 100644 --- a/x/farming/spec/08_params.md +++ b/x/farming/spec/08_params.md @@ -16,7 +16,7 @@ Fee paid for to create a Private type Farming plan. This fee prevents spamming a ## NextEpochDays -`NextEpochDays` is the epoch length in number of days. Internally, the farming module uses `GlobalCurrentEpochDays` to process staking and reward distribution in end blocker because using `NextEpochDays` directly will affect farming rewards allocation. +`NextEpochDays` is the epoch length in number of days. Internally, the farming module uses `CurrentEpochDays` parameter to process staking and reward distribution in end blocker because using `NextEpochDays` directly will affect farming rewards allocation. ## FarmingFeeCollector diff --git a/x/farming/types/farming.pb.go b/x/farming/types/farming.pb.go index 04453e5f..a52163f3 100644 --- a/x/farming/types/farming.pb.go +++ b/x/farming/types/farming.pb.go @@ -68,7 +68,7 @@ type Params struct { // this fee prevents from spamming and it is collected in the community pool PrivatePlanCreationFee github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=private_plan_creation_fee,json=privatePlanCreationFee,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"private_plan_creation_fee" yaml:"private_plan_creation_fee"` // next_epoch_days is the epoch length in number of days - // it updates internal parameter called GlobalCurrentEpochDays that is used to process + // it updates internal parameter called CurrentEpochDays that is used to process // staking and reward distribution in end blocker NextEpochDays uint32 `protobuf:"varint,2,opt,name=next_epoch_days,json=nextEpochDays,proto3" json:"next_epoch_days,omitempty" yaml:"next_epoch_days"` // farming_fee_collector is the module account address to collect fees within the farming module diff --git a/x/farming/types/keys.go b/x/farming/types/keys.go index 2bd2ca85..2fb06cb1 100644 --- a/x/farming/types/keys.go +++ b/x/farming/types/keys.go @@ -23,9 +23,9 @@ const ( // keys for farming store prefixes var ( - GlobalPlanIdKey = []byte("globalPlanId") - GlobalLastEpochTimeKey = []byte("globalLastEpochTime") - GlobalCurrentEpochDaysKey = []byte("globalCurrentEpochDays") + GlobalPlanIdKey = []byte("globalPlanId") + GlobalLastEpochTimeKey = []byte("globalLastEpochTime") + CurrentEpochDaysKey = []byte("currentEpochDays") PlanKeyPrefix = []byte{0x11} From c594268f9c16c2bd546ed3037267eaa943bf0676 Mon Sep 17 00:00:00 2001 From: kogisin Date: Wed, 15 Sep 2021 22:16:58 +0900 Subject: [PATCH 15/20] test: improve code coverage --- x/farming/keeper/epoch_test.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/x/farming/keeper/epoch_test.go b/x/farming/keeper/epoch_test.go index 2d9d5b72..dd3cda1e 100644 --- a/x/farming/keeper/epoch_test.go +++ b/x/farming/keeper/epoch_test.go @@ -72,3 +72,14 @@ func (suite *KeeperTestSuite) TestEpochDays() { }) } } + +func (suite *KeeperTestSuite) TestCurrentEpochDays() { + currentEpochDays := suite.keeper.GetCurrentEpochDays(suite.ctx) + suite.Require().Equal(uint32(1), currentEpochDays) + + nextEpochDays := uint32(3) + suite.keeper.SetCurrentEpochDays(suite.ctx, nextEpochDays) + + currentEpochDays = suite.keeper.GetCurrentEpochDays(suite.ctx) + suite.Require().Equal(uint32(3), currentEpochDays) +} From 7146c75e6c472f595b1451f409484fbedfb60c09 Mon Sep 17 00:00:00 2001 From: kogisin Date: Thu, 16 Sep 2021 14:38:34 +0900 Subject: [PATCH 16/20] chore: apply code review feedbacks and suggestions --- .../tendermint/farming/v1beta1/genesis.proto | 3 + x/farming/abci_test.go | 96 +++++------- x/farming/keeper/epoch.go | 4 +- x/farming/keeper/genesis.go | 6 +- x/farming/spec/02_state.md | 2 + x/farming/types/genesis.go | 7 +- x/farming/types/genesis.pb.go | 146 +++++++++++------- 7 files changed, 142 insertions(+), 122 deletions(-) diff --git a/proto/tendermint/farming/v1beta1/genesis.proto b/proto/tendermint/farming/v1beta1/genesis.proto index 8da7a77b..d3052238 100644 --- a/proto/tendermint/farming/v1beta1/genesis.proto +++ b/proto/tendermint/farming/v1beta1/genesis.proto @@ -57,6 +57,9 @@ message GenesisState { (gogoproto.nullable) = false, (gogoproto.moretags) = "yaml:\"global_last_epoch_time\"" ]; + + // current_epoch_days specifies the epoch used when allocating farming rewards in end blocker + uint32 current_epoch_days = 10; } // PlanRecord is used for import/export via genesis json. diff --git a/x/farming/abci_test.go b/x/farming/abci_test.go index bb094fc0..e4466fcd 100644 --- a/x/farming/abci_test.go +++ b/x/farming/abci_test.go @@ -9,76 +9,56 @@ import ( _ "github.com/stretchr/testify/suite" ) -func (suite *ModuleTestSuite) TestEndBlockerEdgeCase1() { - suite.SetupTest() +func (suite *ModuleTestSuite) TestEndBlockerEpochDaysTest() { + epochDaysTest := func(formerEpochDays, targetNextEpochDays uint32) { + suite.SetupTest() - nextEpochDays := uint32(7) + params := suite.keeper.GetParams(suite.ctx) + params.NextEpochDays = formerEpochDays + suite.keeper.SetParams(suite.ctx, params) + suite.keeper.SetCurrentEpochDays(suite.ctx, formerEpochDays) - params := suite.keeper.GetParams(suite.ctx) - params.NextEpochDays = nextEpochDays - suite.keeper.SetParams(suite.ctx, params) - suite.keeper.SetCurrentEpochDays(suite.ctx, params.NextEpochDays) - - t := types.ParseTime("2021-08-01T00:00:00Z") - suite.ctx = suite.ctx.WithBlockTime(t) - farming.EndBlocker(suite.ctx, suite.keeper) - - lastEpochTime, _ := suite.keeper.GetLastEpochTime(suite.ctx) - - for i := 1; i < 200; i++ { - t = t.Add(1 * time.Hour) + t := types.ParseTime("2021-08-01T00:00:00Z") suite.ctx = suite.ctx.WithBlockTime(t) farming.EndBlocker(suite.ctx, suite.keeper) - if i == 120 { // 5 days passed - params := suite.keeper.GetParams(suite.ctx) - params.NextEpochDays = uint32(1) - suite.keeper.SetParams(suite.ctx, params) - } - - currentEpochDays := suite.keeper.GetCurrentEpochDays(suite.ctx) - - t2, _ := suite.keeper.GetLastEpochTime(suite.ctx) - if t2.After(lastEpochTime) { - suite.Require().GreaterOrEqual(t2.Sub(lastEpochTime).Hours(), float64(nextEpochDays*24)) - suite.Require().Equal(uint32(1), currentEpochDays) - } - } -} - -func (suite *ModuleTestSuite) TestEndBlockerEdgeCase2() { - suite.SetupTest() + lastEpochTime, _ := suite.keeper.GetLastEpochTime(suite.ctx) - nextEpochDays := uint32(1) + for i := 1; i < 200; i++ { + t = t.Add(1 * time.Hour) + suite.ctx = suite.ctx.WithBlockTime(t) + farming.EndBlocker(suite.ctx, suite.keeper) - params := suite.keeper.GetParams(suite.ctx) - params.NextEpochDays = nextEpochDays - suite.keeper.SetParams(suite.ctx, params) - suite.keeper.SetCurrentEpochDays(suite.ctx, params.NextEpochDays) + if i == 10 { // 10 hours passed + params := suite.keeper.GetParams(suite.ctx) + params.NextEpochDays = targetNextEpochDays + suite.keeper.SetParams(suite.ctx, params) + } - t := types.ParseTime("2021-08-01T00:00:00Z") - suite.ctx = suite.ctx.WithBlockTime(t) - farming.EndBlocker(suite.ctx, suite.keeper) + currentEpochDays := suite.keeper.GetCurrentEpochDays(suite.ctx) + t2, _ := suite.keeper.GetLastEpochTime(suite.ctx) - lastEpochTime, _ := suite.keeper.GetLastEpochTime(suite.ctx) + if uint32(i) == formerEpochDays*24 { + suite.Require().True(t2.After(lastEpochTime)) + suite.Require().Equal(t2.Sub(lastEpochTime).Hours(), float64(formerEpochDays*24)) + suite.Require().Equal(targetNextEpochDays, currentEpochDays) + } - for i := 1; i < 50; i++ { - t = t.Add(1 * time.Hour) - suite.ctx = suite.ctx.WithBlockTime(t) - farming.EndBlocker(suite.ctx, suite.keeper) + if uint32(i) == formerEpochDays*24+targetNextEpochDays*24 { + suite.Require().Equal(t2.Sub(lastEpochTime).Hours(), float64(currentEpochDays*24)) + suite.Require().Equal(targetNextEpochDays, currentEpochDays) + } - if i == 10 { // 10 hours passed - params := suite.keeper.GetParams(suite.ctx) - params.NextEpochDays = uint32(7) - suite.keeper.SetParams(suite.ctx, params) + lastEpochTime = t2 } + } - currentEpochDays := suite.keeper.GetCurrentEpochDays(suite.ctx) + // increasing case + epochDaysTest(1, 7) - t2, _ := suite.keeper.GetLastEpochTime(suite.ctx) - if t2.After(lastEpochTime) { - suite.Require().GreaterOrEqual(t2.Sub(lastEpochTime).Hours(), float64(nextEpochDays*24)) - suite.Require().Equal(uint32(7), currentEpochDays) - } - } + // decreasing case + epochDaysTest(7, 1) + + // stay case + epochDaysTest(1, 1) } diff --git a/x/farming/keeper/epoch.go b/x/farming/keeper/epoch.go index bfd3a17e..f833ba47 100644 --- a/x/farming/keeper/epoch.go +++ b/x/farming/keeper/epoch.go @@ -51,8 +51,8 @@ func (k Keeper) GetCurrentEpochDays(ctx sdk.Context) uint32 { store := ctx.KVStore(k.storeKey) bz := store.Get(types.CurrentEpochDaysKey) if bz == nil { - // initialize the current epoch days - epochDays = 1 + // initialize with next epoch days + epochDays = k.GetParams(ctx).NextEpochDays } else { val := gogotypes.UInt32Value{} if err := k.cdc.Unmarshal(bz, &val); err != nil { diff --git a/x/farming/keeper/genesis.go b/x/farming/keeper/genesis.go index f078e9cd..92caf21e 100644 --- a/x/farming/keeper/genesis.go +++ b/x/farming/keeper/genesis.go @@ -11,7 +11,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, genState types.GenesisState) { ctx, applyCache := ctx.CacheContext() k.SetParams(ctx, genState.Params) - k.SetCurrentEpochDays(ctx, genState.Params.NextEpochDays) + k.SetCurrentEpochDays(ctx, genState.CurrentEpochDays) moduleAcc := k.accountKeeper.GetModuleAccount(ctx, types.ModuleName) k.accountKeeper.SetModuleAccount(ctx, moduleAcc) @@ -109,5 +109,7 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { currentEpochs, k.bankKeeper.GetAllBalances(ctx, types.StakingReserveAcc), k.bankKeeper.GetAllBalances(ctx, types.RewardsReserveAcc), - epochTime) + epochTime, + k.GetCurrentEpochDays(ctx), + ) } diff --git a/x/farming/spec/02_state.md b/x/farming/spec/02_state.md index 25c53cd0..578a72bd 100644 --- a/x/farming/spec/02_state.md +++ b/x/farming/spec/02_state.md @@ -120,6 +120,8 @@ The parameters of the Plan state are: - GlobalLastEpochTime: `[]byte("globalLastEpochTime") -> ProtocolBuffer(Timestamp)` +- CurrentEpochDays: `[]byte("currentEpochDays") -> uint32` + ## Staking ```go diff --git a/x/farming/types/genesis.go b/x/farming/types/genesis.go index 0c988ab1..5c483882 100644 --- a/x/farming/types/genesis.go +++ b/x/farming/types/genesis.go @@ -11,7 +11,7 @@ import ( func NewGenesisState( params Params, plans []PlanRecord, stakings []StakingRecord, queuedStakings []QueuedStakingRecord, historicalRewards []HistoricalRewardsRecord, currentEpochs []CurrentEpochRecord, stakingReserveCoins, - rewardPoolCoins sdk.Coins, globalLastEpochTime time.Time, + rewardPoolCoins sdk.Coins, globalLastEpochTime time.Time, currentEpochDays uint32, ) *GenesisState { return &GenesisState{ Params: params, @@ -23,6 +23,7 @@ func NewGenesisState( StakingReserveCoins: stakingReserveCoins, RewardPoolCoins: rewardPoolCoins, GlobalLastEpochTime: globalLastEpochTime, + CurrentEpochDays: currentEpochDays, } } @@ -37,7 +38,9 @@ func DefaultGenesisState() *GenesisState { []CurrentEpochRecord{}, sdk.Coins{}, sdk.Coins{}, - time.Time{}) + time.Time{}, + 1, + ) } // ValidateGenesis validates GenesisState. diff --git a/x/farming/types/genesis.pb.go b/x/farming/types/genesis.pb.go index ad428f0d..c0754394 100644 --- a/x/farming/types/genesis.pb.go +++ b/x/farming/types/genesis.pb.go @@ -49,6 +49,8 @@ type GenesisState struct { RewardPoolCoins github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,8,rep,name=reward_pool_coins,json=rewardPoolCoins,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"reward_pool_coins" yaml:"reward_pool_coins"` // global_last_epoch_time specifies the last executed epoch time of the plans GlobalLastEpochTime time.Time `protobuf:"bytes,9,opt,name=global_last_epoch_time,json=globalLastEpochTime,proto3,stdtime" json:"global_last_epoch_time" yaml:"global_last_epoch_time"` + // current_epoch_days specifies the epoch used when allocating farming rewards in end blocker + CurrentEpochDays uint32 `protobuf:"varint,10,opt,name=current_epoch_days,json=currentEpochDays,proto3" json:"current_epoch_days,omitempty"` } func (m *GenesisState) Reset() { *m = GenesisState{} } @@ -298,65 +300,66 @@ func init() { } var fileDescriptor_c67612b66bcd2967 = []byte{ - // 919 bytes of a gzipped FileDescriptorProto + // 942 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0xcf, 0x6f, 0xdc, 0x44, - 0x14, 0xde, 0xc9, 0x26, 0x69, 0x33, 0x49, 0xfa, 0x63, 0x76, 0xb3, 0x38, 0x81, 0xd8, 0xad, 0x45, - 0xa4, 0x14, 0x14, 0x5b, 0x2d, 0x07, 0xa4, 0x0a, 0x84, 0x30, 0x20, 0x40, 0x2d, 0x52, 0x98, 0x72, - 0xe2, 0x62, 0xcd, 0x7a, 0xa7, 0x8e, 0x15, 0xdb, 0xe3, 0x7a, 0xbc, 0x85, 0xc0, 0x11, 0x0e, 0x15, - 0x5c, 0x2a, 0x21, 0x21, 0x6e, 0xf4, 0x88, 0x7a, 0xe6, 0xce, 0xb5, 0xe2, 0xd4, 0x23, 0xa7, 0x14, - 0x25, 0x17, 0xae, 0xf4, 0x2f, 0x40, 0xf3, 0x63, 0xbd, 0xde, 0xd8, 0x26, 0xad, 0x54, 0x21, 0x4e, - 0xeb, 0x99, 0x79, 0xef, 0xfb, 0xbe, 0xf7, 0x66, 0xde, 0x7b, 0x0b, 0xb7, 0x0b, 0x9a, 0x8e, 0x68, - 0x9e, 0x44, 0x69, 0xe1, 0xde, 0x26, 0xe2, 0x37, 0x74, 0xef, 0x5e, 0x1d, 0xd2, 0x82, 0x5c, 0x75, - 0x43, 0x9a, 0x52, 0x1e, 0x71, 0x27, 0xcb, 0x59, 0xc1, 0xd0, 0x20, 0x60, 0x3c, 0x61, 0xdc, 0xd1, - 0x56, 0x8e, 0xb6, 0xda, 0x58, 0x0f, 0x19, 0x0b, 0x63, 0xea, 0x4a, 0xab, 0xe1, 0xf8, 0xb6, 0x4b, - 0xd2, 0x03, 0xe5, 0xb2, 0xd1, 0x0f, 0x59, 0xc8, 0xe4, 0xa7, 0x2b, 0xbe, 0xf4, 0xee, 0xba, 0x02, - 0xf2, 0xd5, 0x81, 0x46, 0x55, 0x47, 0xa6, 0x5a, 0xb9, 0x43, 0xc2, 0x69, 0x29, 0x23, 0x60, 0x51, - 0xaa, 0xcf, 0xff, 0x4d, 0xed, 0x44, 0x97, 0xb2, 0xb4, 0x4e, 0xaa, 0x2a, 0xa2, 0x84, 0xf2, 0x82, - 0x24, 0x99, 0x32, 0xb0, 0xbf, 0x5f, 0x82, 0x2b, 0x1f, 0xaa, 0x00, 0x6f, 0x15, 0xa4, 0xa0, 0xe8, - 0x2d, 0xb8, 0x98, 0x91, 0x9c, 0x24, 0xdc, 0x00, 0x97, 0xc0, 0xf6, 0xf2, 0x35, 0xd3, 0x69, 0x0e, - 0xd8, 0xd9, 0x95, 0x56, 0xde, 0xfc, 0xa3, 0x43, 0xab, 0x83, 0xb5, 0x0f, 0x1a, 0xc2, 0x95, 0x2c, - 0x26, 0xa9, 0x9f, 0xd3, 0x80, 0xe5, 0x23, 0x6e, 0xcc, 0x5d, 0xea, 0x6e, 0x2f, 0x5f, 0xb3, 0x5b, - 0x31, 0x62, 0x92, 0x62, 0x69, 0xea, 0xbd, 0x2c, 0x70, 0x9e, 0x1e, 0x5a, 0xbd, 0x03, 0x92, 0xc4, - 0xd7, 0xed, 0x2a, 0x8a, 0x8d, 0x97, 0xb3, 0xd2, 0x90, 0xa3, 0x14, 0x9e, 0xe7, 0x05, 0xd9, 0x8f, - 0xd2, 0xb0, 0xa4, 0xe9, 0x4a, 0x9a, 0xad, 0x36, 0x9a, 0x5b, 0xca, 0x5c, 0x33, 0x99, 0x9a, 0x69, - 0xa0, 0x98, 0x4e, 0x60, 0xd9, 0xf8, 0x1c, 0xaf, 0x9a, 0x73, 0x74, 0x0f, 0xc0, 0xc1, 0x9d, 0x31, - 0x1d, 0xd3, 0x91, 0x7f, 0x92, 0x77, 0x5e, 0xf2, 0xbe, 0xde, 0xc6, 0xfb, 0xa9, 0xf4, 0x9a, 0x65, - 0xdf, 0xd2, 0xec, 0x9b, 0x8a, 0xbd, 0x19, 0xd8, 0xc6, 0xfd, 0x3b, 0x75, 0x5f, 0x8e, 0x7e, 0x02, - 0x70, 0x63, 0x2f, 0xe2, 0x05, 0xcb, 0xa3, 0x80, 0xc4, 0x7e, 0x4e, 0xbf, 0x20, 0xf9, 0x88, 0x97, - 0x72, 0x16, 0xa4, 0x1c, 0xb7, 0x4d, 0xce, 0x47, 0xa5, 0x27, 0x56, 0x8e, 0x5a, 0xd2, 0x15, 0x2d, - 0xe9, 0xb2, 0x92, 0xd4, 0x4e, 0x60, 0x63, 0x63, 0xaf, 0x19, 0x83, 0xa3, 0x6f, 0x01, 0x5c, 0x0b, - 0xc6, 0x79, 0x4e, 0xd3, 0xc2, 0xa7, 0x19, 0x0b, 0xf6, 0x4a, 0x55, 0x8b, 0x52, 0xd5, 0x6b, 0x6d, - 0xaa, 0xde, 0x53, 0x4e, 0x1f, 0x08, 0x1f, 0x2d, 0xe8, 0x55, 0x2d, 0xe8, 0x15, 0x25, 0xa8, 0x11, - 0xd6, 0xc6, 0xbd, 0xa0, 0xe6, 0xc9, 0xd1, 0xcf, 0x00, 0xae, 0x4d, 0x93, 0xc9, 0x69, 0x7e, 0x97, - 0xfa, 0xa2, 0x72, 0xb8, 0x71, 0x46, 0xca, 0x58, 0x9f, 0xc8, 0x10, 0xb5, 0x35, 0xd5, 0xc0, 0xa2, - 0xd4, 0xdb, 0x9d, 0x65, 0x6d, 0x44, 0xb1, 0x1f, 0x3e, 0xb1, 0xb6, 0xc3, 0xa8, 0xd8, 0x1b, 0x0f, - 0x9d, 0x80, 0x25, 0xba, 0x6c, 0xf5, 0xcf, 0x0e, 0x1f, 0xed, 0xbb, 0xc5, 0x41, 0x46, 0xb9, 0x04, - 0xe4, 0xb8, 0x57, 0xbe, 0x24, 0x09, 0x21, 0x37, 0xd1, 0x0f, 0x00, 0x5e, 0x54, 0x79, 0xf5, 0x33, - 0xc6, 0x62, 0xad, 0xee, 0xec, 0x69, 0xea, 0x6e, 0x6a, 0x75, 0x86, 0x52, 0x57, 0x43, 0x78, 0x3e, - 0x65, 0xe7, 0x95, 0xff, 0x2e, 0x63, 0xb1, 0x52, 0xf5, 0x15, 0x1c, 0x84, 0x31, 0x1b, 0x92, 0xd8, - 0x8f, 0x09, 0x9f, 0xa4, 0x5a, 0x34, 0x0b, 0x63, 0x49, 0xb6, 0x81, 0x0d, 0x47, 0x75, 0x12, 0x67, - 0xd2, 0x49, 0x9c, 0xcf, 0x26, 0x9d, 0xa4, 0x7c, 0x3f, 0xfa, 0x49, 0x37, 0xe3, 0xd8, 0xf7, 0x9f, - 0x58, 0x00, 0xf7, 0xd4, 0xe1, 0x4d, 0xc2, 0xd5, 0xb5, 0x09, 0x90, 0xeb, 0x67, 0xef, 0x3d, 0xb0, - 0x3a, 0x7f, 0x3d, 0xb0, 0x3a, 0xf6, 0x77, 0x5d, 0x08, 0xa7, 0x3d, 0x01, 0xbd, 0x09, 0xe7, 0x45, - 0xe1, 0xeb, 0x4e, 0xd4, 0xaf, 0x49, 0x78, 0x37, 0x3d, 0xf0, 0x56, 0x05, 0xf9, 0xef, 0xbf, 0xee, - 0x2c, 0x08, 0xbf, 0x8f, 0xb1, 0x74, 0x40, 0x3f, 0x02, 0x88, 0xf4, 0x3b, 0xab, 0x26, 0x79, 0xee, - 0xb4, 0x24, 0x7f, 0xa2, 0x23, 0x59, 0x57, 0x91, 0xd4, 0x21, 0x9e, 0x2f, 0xcb, 0x17, 0x34, 0xc0, - 0x34, 0xcd, 0xed, 0xcf, 0xb3, 0xfb, 0xff, 0x78, 0x9e, 0x95, 0xcb, 0xf8, 0x0d, 0xc0, 0xd5, 0x99, - 0xfe, 0x83, 0x6e, 0x40, 0x34, 0xa1, 0x15, 0x74, 0xfe, 0x88, 0xa6, 0x2c, 0x91, 0xb7, 0xb3, 0xe4, - 0x6d, 0x4e, 0xd3, 0x56, 0xb7, 0xb1, 0xf1, 0x05, 0xbd, 0x29, 0x48, 0xde, 0x17, 0x5b, 0x68, 0x00, - 0x17, 0x45, 0x7a, 0x68, 0x6e, 0xcc, 0x09, 0x00, 0xac, 0x57, 0xe8, 0x1d, 0x78, 0x46, 0xdb, 0x1a, - 0x5d, 0x79, 0xef, 0xd6, 0x29, 0x6d, 0x5d, 0x8f, 0xa0, 0x89, 0x57, 0x25, 0x82, 0xbf, 0x01, 0xec, - 0x35, 0xf4, 0xe0, 0xff, 0x26, 0x8e, 0x7d, 0x78, 0x6e, 0xb6, 0xb9, 0xeb, 0x70, 0xb6, 0x9e, 0x69, - 0x5a, 0x78, 0x9b, 0xfa, 0xba, 0xd7, 0x9a, 0xe6, 0x84, 0x8d, 0x57, 0x67, 0xe6, 0x43, 0x25, 0xe6, - 0x6f, 0xe6, 0xe0, 0x4b, 0x2d, 0x8d, 0xfe, 0xc5, 0xc6, 0xdd, 0x87, 0x0b, 0xb2, 0xba, 0x65, 0xd8, - 0xf3, 0x58, 0x2d, 0xd0, 0xd7, 0x10, 0xd5, 0xe7, 0x87, 0x8e, 0xfc, 0xca, 0x33, 0x0f, 0x26, 0xef, - 0xf2, 0x6c, 0x21, 0xd6, 0x21, 0x6d, 0x7c, 0xb1, 0x36, 0x8a, 0x2a, 0x59, 0x78, 0x08, 0x20, 0xaa, - 0x0f, 0x96, 0x17, 0x9b, 0x80, 0xb7, 0xe1, 0xea, 0xcc, 0x64, 0x52, 0x89, 0xf0, 0x8c, 0xa7, 0x87, - 0x56, 0xbf, 0x61, 0x70, 0xd9, 0x78, 0xa5, 0x3a, 0xb0, 0xa6, 0x62, 0xbd, 0x1b, 0xbf, 0x1c, 0x99, - 0xe0, 0xd1, 0x91, 0x09, 0x1e, 0x1f, 0x99, 0xe0, 0xcf, 0x23, 0x13, 0xdc, 0x3f, 0x36, 0x3b, 0x8f, - 0x8f, 0xcd, 0xce, 0x1f, 0xc7, 0x66, 0xe7, 0xf3, 0x9d, 0x4a, 0x3d, 0x37, 0xfc, 0xef, 0xfb, 0xb2, - 0xfc, 0x92, 0xa5, 0x3d, 0x5c, 0x94, 0xdd, 0xf1, 0x8d, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x6e, - 0xb1, 0x07, 0x4d, 0xd2, 0x0a, 0x00, 0x00, + 0x14, 0xde, 0xc9, 0x26, 0x69, 0x33, 0xc9, 0xb6, 0xe9, 0xec, 0x66, 0x71, 0x02, 0xb1, 0x53, 0x8b, + 0x48, 0x5b, 0x20, 0xb6, 0x5a, 0x0e, 0x48, 0x15, 0x08, 0x61, 0x8a, 0x00, 0xb5, 0x48, 0x61, 0xca, + 0x89, 0x8b, 0x35, 0xbb, 0x3b, 0x75, 0xac, 0x78, 0x3d, 0x5b, 0x8f, 0xb7, 0xb0, 0x70, 0x84, 0x43, + 0xc5, 0xa9, 0x12, 0x12, 0xe2, 0x46, 0x8f, 0xa8, 0x67, 0x2e, 0x9c, 0xb8, 0x56, 0x9c, 0x7a, 0xe4, + 0x94, 0xa2, 0xcd, 0x85, 0x2b, 0xfd, 0x0b, 0xd0, 0xfc, 0x58, 0xaf, 0x37, 0xb6, 0x49, 0x2b, 0x45, + 0x88, 0xd3, 0xda, 0x9e, 0xf7, 0xbe, 0xef, 0x7b, 0xef, 0xcd, 0x7b, 0x6f, 0x61, 0x27, 0xa5, 0x71, + 0x9f, 0x26, 0x83, 0x30, 0x4e, 0xdd, 0x3b, 0x44, 0xfc, 0x06, 0xee, 0xbd, 0xab, 0x5d, 0x9a, 0x92, + 0xab, 0x6e, 0x40, 0x63, 0xca, 0x43, 0xee, 0x0c, 0x13, 0x96, 0x32, 0xd4, 0xee, 0x31, 0x3e, 0x60, + 0xdc, 0xd1, 0x56, 0x8e, 0xb6, 0xda, 0xda, 0x0c, 0x18, 0x0b, 0x22, 0xea, 0x4a, 0xab, 0xee, 0xe8, + 0x8e, 0x4b, 0xe2, 0xb1, 0x72, 0xd9, 0x6a, 0x05, 0x2c, 0x60, 0xf2, 0xd1, 0x15, 0x4f, 0xfa, 0xeb, + 0xa6, 0x02, 0xf2, 0xd5, 0x81, 0x46, 0x55, 0x47, 0xa6, 0x7a, 0x73, 0xbb, 0x84, 0xd3, 0x4c, 0x46, + 0x8f, 0x85, 0xb1, 0x3e, 0xff, 0x37, 0xb5, 0x53, 0x5d, 0xca, 0xd2, 0x3a, 0xa9, 0x2a, 0x0d, 0x07, + 0x94, 0xa7, 0x64, 0x30, 0x54, 0x06, 0xf6, 0xaf, 0x2b, 0x70, 0xed, 0x43, 0x15, 0xe0, 0xed, 0x94, + 0xa4, 0x14, 0xbd, 0x0d, 0x97, 0x87, 0x24, 0x21, 0x03, 0x6e, 0x80, 0x1d, 0xd0, 0x59, 0xbd, 0x66, + 0x3a, 0xe5, 0x01, 0x3b, 0xfb, 0xd2, 0xca, 0x5b, 0x7c, 0x7c, 0x64, 0xd5, 0xb0, 0xf6, 0x41, 0x5d, + 0xb8, 0x36, 0x8c, 0x48, 0xec, 0x27, 0xb4, 0xc7, 0x92, 0x3e, 0x37, 0x16, 0x76, 0xea, 0x9d, 0xd5, + 0x6b, 0x76, 0x25, 0x46, 0x44, 0x62, 0x2c, 0x4d, 0xbd, 0x97, 0x05, 0xce, 0xb3, 0x23, 0xab, 0x39, + 0x26, 0x83, 0xe8, 0xba, 0x9d, 0x47, 0xb1, 0xf1, 0xea, 0x30, 0x33, 0xe4, 0x28, 0x86, 0x17, 0x79, + 0x4a, 0x0e, 0xc3, 0x38, 0xc8, 0x68, 0xea, 0x92, 0x66, 0xb7, 0x8a, 0xe6, 0xb6, 0x32, 0xd7, 0x4c, + 0xa6, 0x66, 0x6a, 0x2b, 0xa6, 0x13, 0x58, 0x36, 0xbe, 0xc0, 0xf3, 0xe6, 0x1c, 0xdd, 0x07, 0xb0, + 0x7d, 0x77, 0x44, 0x47, 0xb4, 0xef, 0x9f, 0xe4, 0x5d, 0x94, 0xbc, 0xaf, 0x57, 0xf1, 0x7e, 0x2a, + 0xbd, 0xe6, 0xd9, 0x77, 0x35, 0xfb, 0xb6, 0x62, 0x2f, 0x07, 0xb6, 0x71, 0xeb, 0x6e, 0xd1, 0x97, + 0xa3, 0x1f, 0x01, 0xdc, 0x3a, 0x08, 0x79, 0xca, 0x92, 0xb0, 0x47, 0x22, 0x3f, 0xa1, 0x5f, 0x90, + 0xa4, 0xcf, 0x33, 0x39, 0x4b, 0x52, 0x8e, 0x5b, 0x25, 0xe7, 0xa3, 0xcc, 0x13, 0x2b, 0x47, 0x2d, + 0xe9, 0x8a, 0x96, 0x74, 0x59, 0x49, 0xaa, 0x26, 0xb0, 0xb1, 0x71, 0x50, 0x8e, 0xc1, 0xd1, 0xb7, + 0x00, 0x6e, 0xf4, 0x46, 0x49, 0x42, 0xe3, 0xd4, 0xa7, 0x43, 0xd6, 0x3b, 0xc8, 0x54, 0x2d, 0x4b, + 0x55, 0xaf, 0x55, 0xa9, 0x7a, 0x5f, 0x39, 0x7d, 0x20, 0x7c, 0xb4, 0xa0, 0x57, 0xb5, 0xa0, 0x57, + 0x94, 0xa0, 0x52, 0x58, 0x1b, 0x37, 0x7b, 0x05, 0x4f, 0x8e, 0x7e, 0x02, 0x70, 0x63, 0x96, 0x4c, + 0x4e, 0x93, 0x7b, 0xd4, 0x17, 0x9d, 0xc3, 0x8d, 0x73, 0x52, 0xc6, 0xe6, 0x54, 0x86, 0xe8, 0xad, + 0x99, 0x06, 0x16, 0xc6, 0xde, 0xfe, 0x3c, 0x6b, 0x29, 0x8a, 0xfd, 0xe8, 0xa9, 0xd5, 0x09, 0xc2, + 0xf4, 0x60, 0xd4, 0x75, 0x7a, 0x6c, 0xa0, 0xdb, 0x56, 0xff, 0xec, 0xf1, 0xfe, 0xa1, 0x9b, 0x8e, + 0x87, 0x94, 0x4b, 0x40, 0x8e, 0x9b, 0xd9, 0x4d, 0x92, 0x10, 0xf2, 0x23, 0xfa, 0x1e, 0xc0, 0x4b, + 0x2a, 0xaf, 0xfe, 0x90, 0xb1, 0x48, 0xab, 0x3b, 0x7f, 0x9a, 0xba, 0x5b, 0x5a, 0x9d, 0xa1, 0xd4, + 0x15, 0x10, 0x5e, 0x4c, 0xd9, 0x45, 0xe5, 0xbf, 0xcf, 0x58, 0xa4, 0x54, 0x7d, 0x05, 0xdb, 0x41, + 0xc4, 0xba, 0x24, 0xf2, 0x23, 0xc2, 0xa7, 0xa9, 0x16, 0xc3, 0xc2, 0x58, 0x91, 0x63, 0x60, 0xcb, + 0x51, 0x93, 0xc4, 0x99, 0x4e, 0x12, 0xe7, 0xb3, 0xe9, 0x24, 0xc9, 0xee, 0x8f, 0xbe, 0xd2, 0xe5, + 0x38, 0xf6, 0x83, 0xa7, 0x16, 0xc0, 0x4d, 0x75, 0x78, 0x8b, 0x70, 0x55, 0x36, 0x01, 0x82, 0xde, + 0x80, 0x68, 0xbe, 0xc4, 0x7d, 0x32, 0xe6, 0x06, 0xdc, 0x01, 0x9d, 0x06, 0x5e, 0xcf, 0x17, 0xf9, + 0x06, 0x19, 0xf3, 0xeb, 0xe7, 0xef, 0x3f, 0xb4, 0x6a, 0x7f, 0x3d, 0xb4, 0x6a, 0xf6, 0x77, 0x75, + 0x08, 0x67, 0x13, 0x04, 0xbd, 0x05, 0x17, 0xc5, 0x98, 0xd0, 0x73, 0xab, 0x55, 0x10, 0xfc, 0x5e, + 0x3c, 0xf6, 0x1a, 0x42, 0xea, 0xef, 0xbf, 0xec, 0x2d, 0x09, 0xbf, 0x8f, 0xb1, 0x74, 0x40, 0x3f, + 0x00, 0x88, 0xf4, 0xad, 0xcc, 0x97, 0x64, 0xe1, 0xb4, 0x92, 0x7c, 0xa2, 0xe3, 0xde, 0x54, 0x71, + 0x17, 0x21, 0x5e, 0xac, 0x26, 0xeb, 0x1a, 0x60, 0x56, 0x94, 0xea, 0xcb, 0x5c, 0xff, 0x7f, 0x5c, + 0xe6, 0x5c, 0x31, 0x7e, 0x03, 0xb0, 0x31, 0x37, 0xad, 0xd0, 0x4d, 0x88, 0xa6, 0xb4, 0x82, 0xce, + 0xef, 0xd3, 0x98, 0x0d, 0x64, 0x75, 0x56, 0xbc, 0xed, 0x59, 0xda, 0x8a, 0x36, 0x36, 0x5e, 0xd7, + 0x1f, 0x05, 0xc9, 0x0d, 0xf1, 0x09, 0xb5, 0xe1, 0xb2, 0x48, 0x0f, 0x4d, 0x8c, 0x05, 0x01, 0x80, + 0xf5, 0x1b, 0x7a, 0x17, 0x9e, 0xd3, 0xb6, 0x46, 0x5d, 0xd6, 0xdd, 0x3a, 0x65, 0x09, 0xe8, 0x85, + 0x35, 0xf5, 0xca, 0x45, 0xf0, 0x37, 0x80, 0xcd, 0x92, 0x89, 0xfd, 0xdf, 0xc4, 0x71, 0x08, 0x2f, + 0xcc, 0xaf, 0x02, 0x1d, 0xce, 0xee, 0x73, 0xed, 0x16, 0x6f, 0x5b, 0x97, 0x7b, 0xa3, 0x6c, 0xab, + 0xd8, 0xb8, 0x31, 0xb7, 0x4d, 0x72, 0x31, 0x7f, 0xb3, 0x00, 0x5f, 0xaa, 0x58, 0x0b, 0x67, 0x1b, + 0x77, 0x0b, 0x2e, 0xc9, 0xde, 0x96, 0x61, 0x2f, 0x62, 0xf5, 0x82, 0xbe, 0x86, 0xa8, 0xb8, 0x6d, + 0x74, 0xe4, 0x57, 0x9e, 0x7b, 0x8d, 0x79, 0x97, 0xe7, 0x1b, 0xb1, 0x08, 0x69, 0xe3, 0x4b, 0x85, + 0xc5, 0x95, 0xcb, 0xc2, 0x23, 0x00, 0x51, 0x71, 0x0d, 0x9d, 0x6d, 0x02, 0xde, 0x81, 0x8d, 0xb9, + 0x21, 0xa7, 0x12, 0xe1, 0x19, 0xcf, 0x8e, 0xac, 0x56, 0xc9, 0x9a, 0xb3, 0xf1, 0x5a, 0x7e, 0xf2, + 0xcd, 0xc4, 0x7a, 0x37, 0x7f, 0x9e, 0x98, 0xe0, 0xf1, 0xc4, 0x04, 0x4f, 0x26, 0x26, 0xf8, 0x73, + 0x62, 0x82, 0x07, 0xc7, 0x66, 0xed, 0xc9, 0xb1, 0x59, 0xfb, 0xe3, 0xd8, 0xac, 0x7d, 0xbe, 0x97, + 0xeb, 0xe7, 0x92, 0x7f, 0x89, 0x5f, 0x66, 0x4f, 0xb2, 0xb5, 0xbb, 0xcb, 0x72, 0x3a, 0xbe, 0xf9, + 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xf8, 0x54, 0x68, 0x3d, 0x00, 0x0b, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -379,6 +382,11 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.CurrentEpochDays != 0 { + i = encodeVarintGenesis(dAtA, i, uint64(m.CurrentEpochDays)) + i-- + dAtA[i] = 0x50 + } n1, err1 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.GlobalLastEpochTime, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.GlobalLastEpochTime):]) if err1 != nil { return 0, err1 @@ -796,6 +804,9 @@ func (m *GenesisState) Size() (n int) { } l = github_com_gogo_protobuf_types.SizeOfStdTime(m.GlobalLastEpochTime) n += 1 + l + sovGenesis(uint64(l)) + if m.CurrentEpochDays != 0 { + n += 1 + sovGenesis(uint64(m.CurrentEpochDays)) + } return n } @@ -1233,6 +1244,25 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpochDays", wireType) + } + m.CurrentEpochDays = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenesis + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurrentEpochDays |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipGenesis(dAtA[iNdEx:]) From 53f8d6f7f409ddd69188105ef775891eab7f7530 Mon Sep 17 00:00:00 2001 From: kogisin Date: Thu, 16 Sep 2021 16:06:37 +0900 Subject: [PATCH 17/20] feat: add gRPC query and cli for current epoch days --- client/docs/swagger-ui/swagger.yaml | 1545 +++--------------- proto/tendermint/farming/v1beta1/query.proto | 13 + x/farming/client/cli/query.go | 37 + x/farming/keeper/grpc_query.go | 12 + x/farming/types/query.pb.go | 398 ++++- x/farming/types/query.pb.gw.go | 62 + 6 files changed, 716 insertions(+), 1351 deletions(-) diff --git a/client/docs/swagger-ui/swagger.yaml b/client/docs/swagger-ui/swagger.yaml index 72dd9a9a..123a626f 100644 --- a/client/docs/swagger-ui/swagger.yaml +++ b/client/docs/swagger-ui/swagger.yaml @@ -4,6 +4,213 @@ info: description: 'A REST interface for state queries, transactions' version: 0.1.1 paths: + /cosmos/farming/v1beta1/current_epoch_days: + get: + summary: CurrentEpochDays returns current epoch days. + operationId: CurrentEpochDays + responses: + '200': + description: A successful response. + schema: + type: object + properties: + current_epoch_days: + type: integer + format: int64 + description: >- + QuerCurrentEpochDaysResponse is the response type for the + Query/CurrentEpochDays RPC method. + default: + description: An unexpected error response + schema: + type: object + properties: + error: + type: string + code: + type: integer + format: int32 + message: + type: string + details: + type: array + items: + type: object + properties: + type_url: + type: string + description: >- + A URL/resource name that uniquely identifies the type of + the serialized + + protocol buffer message. This string must contain at + least + + one "/" character. The last segment of the URL's path + must represent + + the fully qualified name of the type (as in + + `path/google.protobuf.Duration`). The name should be in + a canonical form + + (e.g., leading "." is not accepted). + + + In practice, teams usually precompile into the binary + all types that they + + expect it to use in the context of Any. However, for + URLs which use the + + scheme `http`, `https`, or no scheme, one can optionally + set up a type + + server that maps type URLs to message definitions as + follows: + + + * If no scheme is provided, `https` is assumed. + + * An HTTP GET on the URL must yield a + [google.protobuf.Type][] + value in binary format, or produce an error. + * Applications are allowed to cache lookup results based + on the + URL, or have them precompiled into a binary to avoid any + lookup. Therefore, binary compatibility needs to be preserved + on changes to types. (Use versioned type names to manage + breaking changes.) + + Note: this functionality is not currently available in + the official + + protobuf release, and it is not used for type URLs + beginning with + + type.googleapis.com. + + + Schemes other than `http`, `https` (or the empty scheme) + might be + + used with implementation specific semantics. + value: + type: string + format: byte + description: >- + Must be a valid serialized protocol buffer of the above + specified type. + description: >- + `Any` contains an arbitrary serialized protocol buffer + message along with a + + URL that describes the type of the serialized message. + + + Protobuf library provides support to pack/unpack Any values + in the form + + of utility functions or additional generated methods of the + Any type. + + + Example 1: Pack and unpack a message in C++. + + Foo foo = ...; + Any any; + any.PackFrom(foo); + ... + if (any.UnpackTo(&foo)) { + ... + } + + Example 2: Pack and unpack a message in Java. + + Foo foo = ...; + Any any = Any.pack(foo); + ... + if (any.is(Foo.class)) { + foo = any.unpack(Foo.class); + } + + Example 3: Pack and unpack a message in Python. + + foo = Foo(...) + any = Any() + any.Pack(foo) + ... + if any.Is(Foo.DESCRIPTOR): + any.Unpack(foo) + ... + + Example 4: Pack and unpack a message in Go + + foo := &pb.Foo{...} + any, err := ptypes.MarshalAny(foo) + ... + foo := &pb.Foo{} + if err := ptypes.UnmarshalAny(any, foo); err != nil { + ... + } + + The pack methods provided by protobuf library will by + default use + + 'type.googleapis.com/full.type.name' as the type URL and the + unpack + + methods only use the fully qualified type name after the + last '/' + + in the type URL, for example "foo.bar.com/x/y.z" will yield + type + + name "y.z". + + + + JSON + + ==== + + The JSON representation of an `Any` value uses the regular + + representation of the deserialized, embedded message, with + an + + additional field `@type` which contains the type URL. + Example: + + package google.profile; + message Person { + string first_name = 1; + string last_name = 2; + } + + { + "@type": "type.googleapis.com/google.profile.Person", + "firstName": , + "lastName": + } + + If the embedded message type is well-known and has a custom + JSON + + representation, that representation will be embedded adding + a field + + `value` which holds the custom JSON in addition to the + `@type` + + field. Example (for message [google.protobuf.Duration][]): + + { + "@type": "type.googleapis.com/google.protobuf.Duration", + "value": "1.212s" + } + tags: + - Query /cosmos/farming/v1beta1/params: get: summary: Params returns parameters of the farming module. @@ -40,35 +247,16 @@ paths: this fee prevents from spamming and it is collected in the community pool - staking_creation_fee: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the - custom method - - signatures required by gogoproto. - title: |- - When a farmer creates new staking, the farmer needs to pay - staking_creation_fee to prevent spam on the staking struct - epoch_days: + next_epoch_days: type: integer format: int64 title: >- - The universal epoch length in number of days. Every - process for staking and + next_epoch_days is the epoch length in number of days + + it updates internal parameter called CurrentEpochDays that + is used to process - reward distribution is executed with this epoch_days - frequency + staking and reward distribution in end blocker farming_fee_collector: type: string title: >- @@ -1136,961 +1324,6 @@ paths: format: uint64 tags: - Query - /cosmos/farming/v1beta1/rewards: - get: - summary: Rewards returns all rewards. - operationId: Rewards - responses: - '200': - description: A successful response. - schema: - type: object - properties: - rewards: - type: array - items: - type: object - properties: - farmer: - type: string - title: farmer defines the bech32-encoded address of the farmer - staking_coin_denom: - type: string - title: >- - staking_coin_denom is denom of staked coin as a source - of the reward - reward_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements the - custom method - - signatures required by gogoproto. - title: >- - reward_coins specifies rewards amount at this point in - time when farmers - - receive them from the farming plan - description: Reward defines a record of farming rewards. - pagination: - type: object - properties: - next_key: - type: string - format: byte - title: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently - total: - type: string - format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total - - was set, its value is undefined otherwise - description: >- - PageResponse is to be embedded in gRPC response messages where - the - - corresponding request message has used PageRequest. - - message SomeResponse { - repeated Bar results = 1; - PageResponse page = 2; - } - description: >- - QueryRewardsResponse is the response type for the Query/Rewards - RPC method. - default: - description: An unexpected error response - schema: - type: object - properties: - error: - type: string - code: - type: integer - format: int32 - message: - type: string - details: - type: array - items: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the type of - the serialized - - protocol buffer message. This string must contain at - least - - one "/" character. The last segment of the URL's path - must represent - - the fully qualified name of the type (as in - - `path/google.protobuf.Duration`). The name should be in - a canonical form - - (e.g., leading "." is not accepted). - - - In practice, teams usually precompile into the binary - all types that they - - expect it to use in the context of Any. However, for - URLs which use the - - scheme `http`, `https`, or no scheme, one can optionally - set up a type - - server that maps type URLs to message definitions as - follows: - - - * If no scheme is provided, `https` is assumed. - - * An HTTP GET on the URL must yield a - [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup results based - on the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) - - Note: this functionality is not currently available in - the official - - protobuf release, and it is not used for type URLs - beginning with - - type.googleapis.com. - - - Schemes other than `http`, `https` (or the empty scheme) - might be - - used with implementation specific semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer of the above - specified type. - description: >- - `Any` contains an arbitrary serialized protocol buffer - message along with a - - URL that describes the type of the serialized message. - - - Protobuf library provides support to pack/unpack Any values - in the form - - of utility functions or additional generated methods of the - Any type. - - - Example 1: Pack and unpack a message in C++. - - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - - Example 2: Pack and unpack a message in Java. - - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } - - Example 3: Pack and unpack a message in Python. - - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... - - Example 4: Pack and unpack a message in Go - - foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) - ... - foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { - ... - } - - The pack methods provided by protobuf library will by - default use - - 'type.googleapis.com/full.type.name' as the type URL and the - unpack - - methods only use the fully qualified type name after the - last '/' - - in the type URL, for example "foo.bar.com/x/y.z" will yield - type - - name "y.z". - - - - JSON - - ==== - - The JSON representation of an `Any` value uses the regular - - representation of the deserialized, embedded message, with - an - - additional field `@type` which contains the type URL. - Example: - - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } - - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } - - If the embedded message type is well-known and has a custom - JSON - - representation, that representation will be embedded adding - a field - - `value` which holds the custom JSON in addition to the - `@type` - - field. Example (for message [google.protobuf.Duration][]): - - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - parameters: - - name: farmer - in: query - required: false - type: string - - name: staking_coin_denom - in: query - required: false - type: string - - name: pagination.key - description: |- - key is a value returned in PageResponse.next_key to begin - querying the next page most efficiently. Only one of offset or key - should be set. - in: query - required: false - type: string - format: byte - - name: pagination.offset - description: >- - offset is a numeric offset that can be used when key is unavailable. - - It is less efficient than using key. Only one of offset or key - should - - be set. - in: query - required: false - type: string - format: uint64 - - name: pagination.limit - description: >- - limit is the total number of results to be returned in the result - page. - - If left empty it will default to a value to be set by each app. - in: query - required: false - type: string - format: uint64 - - name: pagination.count_total - description: >- - count_total is set to true to indicate that the result set should - include - - a count of the total number of items available for pagination in - UIs. - - count_total is only respected when offset is used. It is ignored - when key - - is set. - in: query - required: false - type: boolean - format: boolean - - name: pagination.reverse - description: >- - reverse is set to true if results are to be returned in the - descending - - order. - in: query - required: false - type: boolean - format: boolean - tags: - - Query - /cosmos/farming/v1beta1/stakings: - get: - summary: Stakings returns all stakings. - operationId: Stakings - responses: - '200': - description: A successful response. - schema: - type: object - properties: - stakings: - type: array - items: - type: object - properties: - id: - type: string - format: uint64 - title: id specifies index of the staking - farmer: - type: string - title: >- - farmer defines the bech32-encoded address of the staker - for the plan - staked_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements the - custom method - - signatures required by gogoproto. - title: >- - staked_coins specifies the staking amount for the plan - of farmer - queued_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an - amount. - - - NOTE: The amount field is an Int which implements the - custom method - - signatures required by gogoproto. - description: >- - queued_coins specifies the coins on standby before - current epoch passes and - - gets staked. - description: Staking defines a farmer's staking information. - pagination: - type: object - properties: - next_key: - type: string - format: byte - title: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently - total: - type: string - format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total - - was set, its value is undefined otherwise - description: >- - PageResponse is to be embedded in gRPC response messages where - the - - corresponding request message has used PageRequest. - - message SomeResponse { - repeated Bar results = 1; - PageResponse page = 2; - } - description: >- - QueryStakingsResponse is the response type for the Query/Stakings - RPC method. - default: - description: An unexpected error response - schema: - type: object - properties: - error: - type: string - code: - type: integer - format: int32 - message: - type: string - details: - type: array - items: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the type of - the serialized - - protocol buffer message. This string must contain at - least - - one "/" character. The last segment of the URL's path - must represent - - the fully qualified name of the type (as in - - `path/google.protobuf.Duration`). The name should be in - a canonical form - - (e.g., leading "." is not accepted). - - - In practice, teams usually precompile into the binary - all types that they - - expect it to use in the context of Any. However, for - URLs which use the - - scheme `http`, `https`, or no scheme, one can optionally - set up a type - - server that maps type URLs to message definitions as - follows: - - - * If no scheme is provided, `https` is assumed. - - * An HTTP GET on the URL must yield a - [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup results based - on the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) - - Note: this functionality is not currently available in - the official - - protobuf release, and it is not used for type URLs - beginning with - - type.googleapis.com. - - - Schemes other than `http`, `https` (or the empty scheme) - might be - - used with implementation specific semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer of the above - specified type. - description: >- - `Any` contains an arbitrary serialized protocol buffer - message along with a - - URL that describes the type of the serialized message. - - - Protobuf library provides support to pack/unpack Any values - in the form - - of utility functions or additional generated methods of the - Any type. - - - Example 1: Pack and unpack a message in C++. - - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - - Example 2: Pack and unpack a message in Java. - - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } - - Example 3: Pack and unpack a message in Python. - - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... - - Example 4: Pack and unpack a message in Go - - foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) - ... - foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { - ... - } - - The pack methods provided by protobuf library will by - default use - - 'type.googleapis.com/full.type.name' as the type URL and the - unpack - - methods only use the fully qualified type name after the - last '/' - - in the type URL, for example "foo.bar.com/x/y.z" will yield - type - - name "y.z". - - - - JSON - - ==== - - The JSON representation of an `Any` value uses the regular - - representation of the deserialized, embedded message, with - an - - additional field `@type` which contains the type URL. - Example: - - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } - - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } - - If the embedded message type is well-known and has a custom - JSON - - representation, that representation will be embedded adding - a field - - `value` which holds the custom JSON in addition to the - `@type` - - field. Example (for message [google.protobuf.Duration][]): - - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - parameters: - - name: farmer - in: query - required: false - type: string - - name: staking_coin_denom - in: query - required: false - type: string - - name: pagination.key - description: |- - key is a value returned in PageResponse.next_key to begin - querying the next page most efficiently. Only one of offset or key - should be set. - in: query - required: false - type: string - format: byte - - name: pagination.offset - description: >- - offset is a numeric offset that can be used when key is unavailable. - - It is less efficient than using key. Only one of offset or key - should - - be set. - in: query - required: false - type: string - format: uint64 - - name: pagination.limit - description: >- - limit is the total number of results to be returned in the result - page. - - If left empty it will default to a value to be set by each app. - in: query - required: false - type: string - format: uint64 - - name: pagination.count_total - description: >- - count_total is set to true to indicate that the result set should - include - - a count of the total number of items available for pagination in - UIs. - - count_total is only respected when offset is used. It is ignored - when key - - is set. - in: query - required: false - type: boolean - format: boolean - - name: pagination.reverse - description: >- - reverse is set to true if results are to be returned in the - descending - - order. - in: query - required: false - type: boolean - format: boolean - tags: - - Query - '/cosmos/farming/v1beta1/stakings/{staking_id}': - get: - summary: Staking returns a specific staking. - operationId: Staking - responses: - '200': - description: A successful response. - schema: - type: object - properties: - staking: - type: object - properties: - id: - type: string - format: uint64 - title: id specifies index of the staking - farmer: - type: string - title: >- - farmer defines the bech32-encoded address of the staker - for the plan - staked_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the - custom method - - signatures required by gogoproto. - title: >- - staked_coins specifies the staking amount for the plan of - farmer - queued_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the - custom method - - signatures required by gogoproto. - description: >- - queued_coins specifies the coins on standby before current - epoch passes and - - gets staked. - description: Staking defines a farmer's staking information. - description: >- - QueryStakingResponse is the response type for the Query/Staking - RPC method. - default: - description: An unexpected error response - schema: - type: object - properties: - error: - type: string - code: - type: integer - format: int32 - message: - type: string - details: - type: array - items: - type: object - properties: - type_url: - type: string - description: >- - A URL/resource name that uniquely identifies the type of - the serialized - - protocol buffer message. This string must contain at - least - - one "/" character. The last segment of the URL's path - must represent - - the fully qualified name of the type (as in - - `path/google.protobuf.Duration`). The name should be in - a canonical form - - (e.g., leading "." is not accepted). - - - In practice, teams usually precompile into the binary - all types that they - - expect it to use in the context of Any. However, for - URLs which use the - - scheme `http`, `https`, or no scheme, one can optionally - set up a type - - server that maps type URLs to message definitions as - follows: - - - * If no scheme is provided, `https` is assumed. - - * An HTTP GET on the URL must yield a - [google.protobuf.Type][] - value in binary format, or produce an error. - * Applications are allowed to cache lookup results based - on the - URL, or have them precompiled into a binary to avoid any - lookup. Therefore, binary compatibility needs to be preserved - on changes to types. (Use versioned type names to manage - breaking changes.) - - Note: this functionality is not currently available in - the official - - protobuf release, and it is not used for type URLs - beginning with - - type.googleapis.com. - - - Schemes other than `http`, `https` (or the empty scheme) - might be - - used with implementation specific semantics. - value: - type: string - format: byte - description: >- - Must be a valid serialized protocol buffer of the above - specified type. - description: >- - `Any` contains an arbitrary serialized protocol buffer - message along with a - - URL that describes the type of the serialized message. - - - Protobuf library provides support to pack/unpack Any values - in the form - - of utility functions or additional generated methods of the - Any type. - - - Example 1: Pack and unpack a message in C++. - - Foo foo = ...; - Any any; - any.PackFrom(foo); - ... - if (any.UnpackTo(&foo)) { - ... - } - - Example 2: Pack and unpack a message in Java. - - Foo foo = ...; - Any any = Any.pack(foo); - ... - if (any.is(Foo.class)) { - foo = any.unpack(Foo.class); - } - - Example 3: Pack and unpack a message in Python. - - foo = Foo(...) - any = Any() - any.Pack(foo) - ... - if any.Is(Foo.DESCRIPTOR): - any.Unpack(foo) - ... - - Example 4: Pack and unpack a message in Go - - foo := &pb.Foo{...} - any, err := ptypes.MarshalAny(foo) - ... - foo := &pb.Foo{} - if err := ptypes.UnmarshalAny(any, foo); err != nil { - ... - } - - The pack methods provided by protobuf library will by - default use - - 'type.googleapis.com/full.type.name' as the type URL and the - unpack - - methods only use the fully qualified type name after the - last '/' - - in the type URL, for example "foo.bar.com/x/y.z" will yield - type - - name "y.z". - - - - JSON - - ==== - - The JSON representation of an `Any` value uses the regular - - representation of the deserialized, embedded message, with - an - - additional field `@type` which contains the type URL. - Example: - - package google.profile; - message Person { - string first_name = 1; - string last_name = 2; - } - - { - "@type": "type.googleapis.com/google.profile.Person", - "firstName": , - "lastName": - } - - If the embedded message type is well-known and has a custom - JSON - - representation, that representation will be embedded adding - a field - - `value` which holds the custom JSON in addition to the - `@type` - - field. Example (for message [google.protobuf.Duration][]): - - { - "@type": "type.googleapis.com/google.protobuf.Duration", - "value": "1.212s" - } - parameters: - - name: staking_id - in: path - required: true - type: string - format: uint64 - tags: - - Query definitions: cosmos.base.query.v1beta1.PageRequest: type: object @@ -2201,37 +1434,31 @@ definitions: this fee prevents from spamming and it is collected in the community pool - staking_creation_fee: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: |- - Coin defines a token with a denomination and an amount. - - NOTE: The amount field is an Int which implements the custom method - signatures required by gogoproto. - title: |- - When a farmer creates new staking, the farmer needs to pay - staking_creation_fee to prevent spam on the staking struct - epoch_days: + next_epoch_days: type: integer format: int64 title: >- - The universal epoch length in number of days. Every process for - staking and + next_epoch_days is the epoch length in number of days - reward distribution is executed with this epoch_days frequency + it updates internal parameter called CurrentEpochDays that is used to + process + + staking and reward distribution in end blocker farming_fee_collector: type: string title: >- farming_fee_collector is the module account address to collect fees within the farming module description: Params defines the set of params for the farming module. + cosmos.farming.v1beta1.QueryCurrentEpochDaysResponse: + type: object + properties: + current_epoch_days: + type: integer + format: int64 + description: >- + QuerCurrentEpochDaysResponse is the response type for the + Query/CurrentEpochDays RPC method. cosmos.farming.v1beta1.QueryParamsResponse: type: object properties: @@ -2260,34 +1487,16 @@ definitions: this fee prevents from spamming and it is collected in the community pool - staking_creation_fee: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - title: |- - When a farmer creates new staking, the farmer needs to pay - staking_creation_fee to prevent spam on the staking struct - epoch_days: + next_epoch_days: type: integer format: int64 title: >- - The universal epoch length in number of days. Every process for - staking and + next_epoch_days is the epoch length in number of days + + it updates internal parameter called CurrentEpochDays that is used + to process - reward distribution is executed with this epoch_days frequency + staking and reward distribution in end blocker farming_fee_collector: type: string title: >- @@ -2651,292 +1860,6 @@ definitions: PageResponse page = 2; } description: QueryPlansResponse is the response type for the Query/Plans RPC method. - cosmos.farming.v1beta1.QueryRewardsResponse: - type: object - properties: - rewards: - type: array - items: - type: object - properties: - farmer: - type: string - title: farmer defines the bech32-encoded address of the farmer - staking_coin_denom: - type: string - title: >- - staking_coin_denom is denom of staked coin as a source of the - reward - reward_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - title: >- - reward_coins specifies rewards amount at this point in time when - farmers - - receive them from the farming plan - description: Reward defines a record of farming rewards. - pagination: - type: object - properties: - next_key: - type: string - format: byte - title: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently - total: - type: string - format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total - - was set, its value is undefined otherwise - description: |- - PageResponse is to be embedded in gRPC response messages where the - corresponding request message has used PageRequest. - - message SomeResponse { - repeated Bar results = 1; - PageResponse page = 2; - } - description: >- - QueryRewardsResponse is the response type for the Query/Rewards RPC - method. - cosmos.farming.v1beta1.QueryStakingResponse: - type: object - properties: - staking: - type: object - properties: - id: - type: string - format: uint64 - title: id specifies index of the staking - farmer: - type: string - title: >- - farmer defines the bech32-encoded address of the staker for the - plan - staked_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - title: staked_coins specifies the staking amount for the plan of farmer - queued_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - description: >- - queued_coins specifies the coins on standby before current epoch - passes and - - gets staked. - description: Staking defines a farmer's staking information. - description: >- - QueryStakingResponse is the response type for the Query/Staking RPC - method. - cosmos.farming.v1beta1.QueryStakingsResponse: - type: object - properties: - stakings: - type: array - items: - type: object - properties: - id: - type: string - format: uint64 - title: id specifies index of the staking - farmer: - type: string - title: >- - farmer defines the bech32-encoded address of the staker for the - plan - staked_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - title: staked_coins specifies the staking amount for the plan of farmer - queued_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: >- - Coin defines a token with a denomination and an amount. - - - NOTE: The amount field is an Int which implements the custom - method - - signatures required by gogoproto. - description: >- - queued_coins specifies the coins on standby before current epoch - passes and - - gets staked. - description: Staking defines a farmer's staking information. - pagination: - type: object - properties: - next_key: - type: string - format: byte - title: |- - next_key is the key to be passed to PageRequest.key to - query the next page most efficiently - total: - type: string - format: uint64 - title: >- - total is total number of results available if - PageRequest.count_total - - was set, its value is undefined otherwise - description: |- - PageResponse is to be embedded in gRPC response messages where the - corresponding request message has used PageRequest. - - message SomeResponse { - repeated Bar results = 1; - PageResponse page = 2; - } - description: >- - QueryStakingsResponse is the response type for the Query/Stakings RPC - method. - cosmos.farming.v1beta1.Reward: - type: object - properties: - farmer: - type: string - title: farmer defines the bech32-encoded address of the farmer - staking_coin_denom: - type: string - title: staking_coin_denom is denom of staked coin as a source of the reward - reward_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: |- - Coin defines a token with a denomination and an amount. - - NOTE: The amount field is an Int which implements the custom method - signatures required by gogoproto. - title: >- - reward_coins specifies rewards amount at this point in time when - farmers - - receive them from the farming plan - description: Reward defines a record of farming rewards. - cosmos.farming.v1beta1.Staking: - type: object - properties: - id: - type: string - format: uint64 - title: id specifies index of the staking - farmer: - type: string - title: farmer defines the bech32-encoded address of the staker for the plan - staked_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: |- - Coin defines a token with a denomination and an amount. - - NOTE: The amount field is an Int which implements the custom method - signatures required by gogoproto. - title: staked_coins specifies the staking amount for the plan of farmer - queued_coins: - type: array - items: - type: object - properties: - denom: - type: string - amount: - type: string - description: |- - Coin defines a token with a denomination and an amount. - - NOTE: The amount field is an Int which implements the custom method - signatures required by gogoproto. - description: >- - queued_coins specifies the coins on standby before current epoch - passes and - - gets staked. - description: Staking defines a farmer's staking information. google.protobuf.Any: type: object properties: diff --git a/proto/tendermint/farming/v1beta1/query.proto b/proto/tendermint/farming/v1beta1/query.proto index ba749fc3..76da64a8 100644 --- a/proto/tendermint/farming/v1beta1/query.proto +++ b/proto/tendermint/farming/v1beta1/query.proto @@ -27,6 +27,11 @@ service Query { rpc Plan(QueryPlanRequest) returns (QueryPlanResponse) { option (google.api.http).get = "/cosmos/farming/v1beta1/plans/{plan_id}"; } + + // CurrentEpochDays returns current epoch days. + rpc CurrentEpochDays(QueryCurrentEpochDaysRequest) returns (QueryCurrentEpochDaysResponse) { + option (google.api.http).get = "/cosmos/farming/v1beta1/current_epoch_days"; + } } // QueryParamsRequest is the request type for the Query/Params RPC method. @@ -62,3 +67,11 @@ message QueryPlanRequest { message QueryPlanResponse { google.protobuf.Any plan = 1 [(cosmos_proto.accepts_interface) = "PlanI"]; } + +// QueryCurrentEpochDaysRequest is the request type for the Query/CurrentEpochDays RPC method. +message QueryCurrentEpochDaysRequest {} + +// QuerCurrentEpochDaysResponse is the response type for the Query/CurrentEpochDays RPC method. +message QueryCurrentEpochDaysResponse { + uint32 current_epoch_days = 1; +} \ No newline at end of file diff --git a/x/farming/client/cli/query.go b/x/farming/client/cli/query.go index 890f96ec..6466fbd1 100644 --- a/x/farming/client/cli/query.go +++ b/x/farming/client/cli/query.go @@ -34,6 +34,7 @@ func GetQueryCmd() *cobra.Command { GetCmdQueryParams(), GetCmdQueryPlans(), GetCmdQueryPlan(), + GetCmdQueryCurrentEpochDays(), ) return farmingQueryCmd @@ -188,3 +189,39 @@ $ %s query %s plan return cmd } + +func GetCmdQueryCurrentEpochDays() *cobra.Command { + cmd := &cobra.Command{ + Use: "current-epoch-days", + Args: cobra.NoArgs, + Short: "Query the value of current epoch days", + Long: strings.TrimSpace( + fmt.Sprintf(`Query the value set as current epoch days. + +Example: +$ %s query %s current-epoch-days +`, + version.AppName, types.ModuleName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientTxContext(cmd) + if err != nil { + return err + } + + queryClient := types.NewQueryClient(clientCtx) + + resp, err := queryClient.CurrentEpochDays(context.Background(), &types.QueryCurrentEpochDaysRequest{}) + if err != nil { + return err + } + + return clientCtx.PrintProto(resp) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} diff --git a/x/farming/keeper/grpc_query.go b/x/farming/keeper/grpc_query.go index 2ff053d0..601ce1f7 100644 --- a/x/farming/keeper/grpc_query.go +++ b/x/farming/keeper/grpc_query.go @@ -145,3 +145,15 @@ func (k Querier) Plan(c context.Context, req *types.QueryPlanRequest) (*types.Qu return &types.QueryPlanResponse{Plan: any}, nil } + +// CurrentEpochDays queries current epoch days. +func (k Querier) CurrentEpochDays(c context.Context, req *types.QueryCurrentEpochDaysRequest) (*types.QueryCurrentEpochDaysResponse, error) { + if req == nil { + return nil, status.Error(codes.InvalidArgument, "invalid request") + } + + ctx := sdk.UnwrapSDKContext(c) + currentEpochDays := k.GetCurrentEpochDays(ctx) + + return &types.QueryCurrentEpochDaysResponse{CurrentEpochDays: currentEpochDays}, nil +} diff --git a/x/farming/types/query.pb.go b/x/farming/types/query.pb.go index 043ffd3d..102628a1 100644 --- a/x/farming/types/query.pb.go +++ b/x/farming/types/query.pb.go @@ -342,6 +342,88 @@ func (m *QueryPlanResponse) GetPlan() *types.Any { return nil } +// QueryCurrentEpochDaysRequest is the request type for the Query/CurrentEpochDays RPC method. +type QueryCurrentEpochDaysRequest struct { +} + +func (m *QueryCurrentEpochDaysRequest) Reset() { *m = QueryCurrentEpochDaysRequest{} } +func (m *QueryCurrentEpochDaysRequest) String() string { return proto.CompactTextString(m) } +func (*QueryCurrentEpochDaysRequest) ProtoMessage() {} +func (*QueryCurrentEpochDaysRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_00c8db58c274b111, []int{6} +} +func (m *QueryCurrentEpochDaysRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryCurrentEpochDaysRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryCurrentEpochDaysRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryCurrentEpochDaysRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryCurrentEpochDaysRequest.Merge(m, src) +} +func (m *QueryCurrentEpochDaysRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryCurrentEpochDaysRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryCurrentEpochDaysRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryCurrentEpochDaysRequest proto.InternalMessageInfo + +// QuerCurrentEpochDaysResponse is the response type for the Query/CurrentEpochDays RPC method. +type QueryCurrentEpochDaysResponse struct { + CurrentEpochDays uint32 `protobuf:"varint,1,opt,name=current_epoch_days,json=currentEpochDays,proto3" json:"current_epoch_days,omitempty"` +} + +func (m *QueryCurrentEpochDaysResponse) Reset() { *m = QueryCurrentEpochDaysResponse{} } +func (m *QueryCurrentEpochDaysResponse) String() string { return proto.CompactTextString(m) } +func (*QueryCurrentEpochDaysResponse) ProtoMessage() {} +func (*QueryCurrentEpochDaysResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_00c8db58c274b111, []int{7} +} +func (m *QueryCurrentEpochDaysResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryCurrentEpochDaysResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryCurrentEpochDaysResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryCurrentEpochDaysResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryCurrentEpochDaysResponse.Merge(m, src) +} +func (m *QueryCurrentEpochDaysResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryCurrentEpochDaysResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryCurrentEpochDaysResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryCurrentEpochDaysResponse proto.InternalMessageInfo + +func (m *QueryCurrentEpochDaysResponse) GetCurrentEpochDays() uint32 { + if m != nil { + return m.CurrentEpochDays + } + return 0 +} + func init() { proto.RegisterType((*QueryParamsRequest)(nil), "cosmos.farming.v1beta1.QueryParamsRequest") proto.RegisterType((*QueryParamsResponse)(nil), "cosmos.farming.v1beta1.QueryParamsResponse") @@ -349,6 +431,8 @@ func init() { proto.RegisterType((*QueryPlansResponse)(nil), "cosmos.farming.v1beta1.QueryPlansResponse") proto.RegisterType((*QueryPlanRequest)(nil), "cosmos.farming.v1beta1.QueryPlanRequest") proto.RegisterType((*QueryPlanResponse)(nil), "cosmos.farming.v1beta1.QueryPlanResponse") + proto.RegisterType((*QueryCurrentEpochDaysRequest)(nil), "cosmos.farming.v1beta1.QueryCurrentEpochDaysRequest") + proto.RegisterType((*QueryCurrentEpochDaysResponse)(nil), "cosmos.farming.v1beta1.QueryCurrentEpochDaysResponse") } func init() { @@ -356,46 +440,51 @@ func init() { } var fileDescriptor_00c8db58c274b111 = []byte{ - // 623 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x54, 0x41, 0x6f, 0x12, 0x41, - 0x14, 0x66, 0xe9, 0x82, 0xe9, 0xf4, 0x52, 0xa7, 0x44, 0x57, 0xa2, 0xdb, 0x66, 0x13, 0x5b, 0xa0, - 0x76, 0xc7, 0xd2, 0x78, 0xf3, 0x52, 0x34, 0xd6, 0xde, 0xea, 0x7a, 0xf3, 0x42, 0x06, 0x76, 0xba, - 0x6e, 0x84, 0x99, 0x2d, 0xb3, 0x18, 0x89, 0xf1, 0x62, 0xe2, 0xc1, 0xc4, 0x83, 0x89, 0xfe, 0x00, - 0xcf, 0x9e, 0xfd, 0x11, 0x8d, 0xa7, 0x26, 0x5e, 0x3c, 0x19, 0x03, 0xfe, 0x10, 0x33, 0x6f, 0x66, - 0x29, 0xa4, 0x2d, 0x70, 0x62, 0xf6, 0xbd, 0xef, 0x7d, 0xef, 0x9b, 0xf7, 0xbe, 0x01, 0x6d, 0xa6, - 0x8c, 0x87, 0xac, 0xd7, 0x8d, 0x79, 0x4a, 0x8e, 0xa9, 0xfa, 0x8d, 0xc8, 0xeb, 0xdd, 0x16, 0x4b, - 0xe9, 0x2e, 0x39, 0xe9, 0xb3, 0xde, 0xc0, 0x4f, 0x7a, 0x22, 0x15, 0xf8, 0x46, 0x5b, 0xc8, 0xae, - 0x90, 0xbe, 0xc1, 0xf8, 0x06, 0x53, 0xae, 0xcc, 0xa8, 0xcf, 0xb0, 0xc0, 0x50, 0xae, 0x69, 0x06, - 0xd2, 0xa2, 0x92, 0x69, 0xea, 0x31, 0x30, 0xa1, 0x51, 0xcc, 0x69, 0x1a, 0x0b, 0x6e, 0xb0, 0xa5, - 0x48, 0x44, 0x02, 0x8e, 0x44, 0x9d, 0x4c, 0xf4, 0x56, 0x24, 0x44, 0xd4, 0x61, 0x04, 0xbe, 0x5a, - 0xfd, 0x63, 0x42, 0xb9, 0x91, 0x57, 0xbe, 0x6d, 0x52, 0x34, 0x89, 0x09, 0xe5, 0x5c, 0xa4, 0xc0, - 0x26, 0xb3, 0x42, 0xdd, 0xba, 0xa9, 0x19, 0xcd, 0x4d, 0xe0, 0xc3, 0x2b, 0x21, 0xfc, 0x4c, 0x69, - 0x39, 0xa2, 0x3d, 0xda, 0x95, 0x01, 0x3b, 0xe9, 0x33, 0x99, 0x7a, 0xcf, 0xd1, 0xda, 0x54, 0x54, - 0x26, 0x82, 0x4b, 0x86, 0x1f, 0xa2, 0x62, 0x02, 0x11, 0xc7, 0xda, 0xb0, 0x2a, 0x2b, 0x75, 0xd7, - 0xbf, 0x7c, 0x2a, 0xbe, 0xae, 0x6b, 0xd8, 0xa7, 0x7f, 0xd6, 0x73, 0x81, 0xa9, 0xf1, 0xbe, 0xe5, - 0xd1, 0x75, 0xcd, 0xda, 0xa1, 0x3c, 0x6b, 0x85, 0x31, 0xb2, 0xd3, 0x41, 0xc2, 0x80, 0x71, 0x39, - 0x80, 0x33, 0xbe, 0x8f, 0x4a, 0x86, 0xb1, 0x99, 0x08, 0xd1, 0x69, 0xd2, 0x30, 0xec, 0x31, 0x29, - 0x9d, 0x3c, 0x60, 0xb0, 0xc9, 0x1d, 0x09, 0xd1, 0xd9, 0xd7, 0x19, 0x4c, 0xd0, 0x5a, 0x0a, 0x5b, - 0x80, 0x7b, 0x8f, 0x0b, 0x96, 0x74, 0xc1, 0x44, 0x2a, 0x2b, 0xb8, 0x87, 0xb0, 0x4c, 0xe9, 0x2b, - 0xd5, 0xa2, 0x2d, 0x62, 0xde, 0x0c, 0x19, 0x17, 0x5d, 0xc7, 0x06, 0xfc, 0xaa, 0xc9, 0x3c, 0x12, - 0x31, 0x7f, 0xac, 0xe2, 0xd8, 0x45, 0x28, 0xe3, 0x60, 0xa1, 0x53, 0x00, 0xd4, 0x44, 0x04, 0x3f, - 0x41, 0xe8, 0x7c, 0x87, 0x4e, 0x11, 0x86, 0xb3, 0x99, 0x0d, 0x47, 0x2d, 0xdc, 0xd7, 0x5e, 0x3a, - 0x9f, 0x4f, 0xc4, 0xcc, 0x00, 0x82, 0x89, 0x4a, 0xef, 0xab, 0x95, 0xad, 0x43, 0x8f, 0xc8, 0xcc, - 0xfd, 0x01, 0x2a, 0x24, 0x2a, 0xe0, 0x58, 0x1b, 0x4b, 0x95, 0x95, 0x7a, 0xc9, 0xd7, 0xdb, 0xf6, - 0x33, 0x23, 0xf8, 0xfb, 0x7c, 0xd0, 0x58, 0xfe, 0xf9, 0x63, 0xa7, 0xa0, 0xea, 0x0e, 0x03, 0x8d, - 0xc6, 0x07, 0x53, 0xaa, 0xf2, 0xa0, 0x6a, 0x6b, 0xae, 0x2a, 0xdd, 0x73, 0x4a, 0xd6, 0x36, 0x5a, - 0x1d, 0xab, 0xca, 0xf6, 0x76, 0x13, 0x5d, 0x53, 0x5d, 0x9a, 0x71, 0x08, 0xab, 0xb3, 0x83, 0xa2, - 0xfa, 0x3c, 0x0c, 0xbd, 0xa7, 0x13, 0x5b, 0x1e, 0xdf, 0x60, 0x0f, 0xd9, 0x2a, 0x6d, 0x7c, 0x33, - 0xf7, 0x02, 0x00, 0xae, 0x7f, 0x5f, 0x42, 0x05, 0xa0, 0xc2, 0x1f, 0x2d, 0x54, 0xd4, 0x9e, 0xc2, - 0xb5, 0xab, 0x3c, 0x77, 0xd1, 0xc6, 0xe5, 0xed, 0x85, 0xb0, 0x5a, 0xa2, 0xb7, 0xf9, 0xfe, 0xd7, - 0xbf, 0x2f, 0xf9, 0x0d, 0xec, 0x9a, 0x07, 0x72, 0xe1, 0x39, 0x6b, 0x1b, 0xe3, 0x0f, 0x16, 0x02, - 0x95, 0x12, 0x57, 0x67, 0xd3, 0x4f, 0xb8, 0xbc, 0x5c, 0x5b, 0x04, 0x6a, 0x84, 0xdc, 0x05, 0x21, - 0xeb, 0xf8, 0xce, 0x95, 0x42, 0xa0, 0xfb, 0x27, 0x0b, 0xd9, 0xaa, 0x10, 0x57, 0xe6, 0x72, 0x67, - 0x2a, 0xaa, 0x0b, 0x20, 0x8d, 0x08, 0x02, 0x22, 0xaa, 0x78, 0x6b, 0xa6, 0x08, 0xf2, 0xd6, 0x78, - 0xe0, 0x5d, 0xe3, 0xe0, 0x74, 0xe8, 0x5a, 0x67, 0x43, 0xd7, 0xfa, 0x3b, 0x74, 0xad, 0xcf, 0x23, - 0x37, 0x77, 0x36, 0x72, 0x73, 0xbf, 0x47, 0x6e, 0xee, 0xc5, 0x4e, 0x14, 0xa7, 0x2f, 0xfb, 0x2d, - 0xbf, 0x2d, 0xba, 0xe4, 0x92, 0x7f, 0xcb, 0x37, 0xe3, 0x93, 0x7a, 0xfb, 0xb2, 0x55, 0x04, 0x53, - 0xec, 0xfd, 0x0f, 0x00, 0x00, 0xff, 0xff, 0x5c, 0xa7, 0x38, 0xa5, 0x9a, 0x05, 0x00, 0x00, + // 704 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x55, 0xcd, 0x6e, 0xd3, 0x4c, + 0x14, 0x8d, 0x53, 0x27, 0x9f, 0x3a, 0xd5, 0x27, 0x85, 0x69, 0x04, 0x21, 0x6a, 0xdd, 0xca, 0x12, + 0x6d, 0x9a, 0xb6, 0x36, 0x4d, 0xe9, 0x8e, 0x4d, 0x7f, 0xa0, 0x74, 0x81, 0x54, 0xcc, 0x8e, 0x8d, + 0x35, 0x89, 0xa7, 0xae, 0x45, 0x32, 0xe3, 0x7a, 0x1c, 0x44, 0x84, 0xd8, 0x20, 0xb1, 0x40, 0x62, + 0x81, 0x04, 0x0f, 0xc0, 0x3b, 0xc0, 0x43, 0x54, 0xac, 0x2a, 0xb1, 0x61, 0x85, 0xaa, 0x96, 0x07, + 0x41, 0x73, 0x67, 0x9c, 0xa6, 0x3f, 0x49, 0xcb, 0x2a, 0x33, 0x73, 0xcf, 0x39, 0xf7, 0xcc, 0xbd, + 0x77, 0x1c, 0x34, 0x97, 0x52, 0x16, 0xd0, 0xa4, 0x13, 0xb1, 0xd4, 0xdd, 0x23, 0xf2, 0x37, 0x74, + 0x5f, 0xad, 0x34, 0x69, 0x4a, 0x56, 0xdc, 0x83, 0x2e, 0x4d, 0x7a, 0x4e, 0x9c, 0xf0, 0x94, 0xe3, + 0xdb, 0x2d, 0x2e, 0x3a, 0x5c, 0x38, 0x1a, 0xe3, 0x68, 0x4c, 0xb5, 0x36, 0x82, 0x9f, 0x61, 0x41, + 0xa1, 0x5a, 0x57, 0x0a, 0x6e, 0x93, 0x08, 0xaa, 0xa4, 0xfb, 0xc0, 0x98, 0x84, 0x11, 0x23, 0x69, + 0xc4, 0x99, 0xc6, 0x96, 0x43, 0x1e, 0x72, 0x58, 0xba, 0x72, 0xa5, 0x4f, 0xef, 0x86, 0x9c, 0x87, + 0x6d, 0xea, 0xc2, 0xae, 0xd9, 0xdd, 0x73, 0x09, 0xd3, 0xf6, 0xaa, 0x53, 0x3a, 0x44, 0xe2, 0xc8, + 0x25, 0x8c, 0xf1, 0x14, 0xd4, 0x44, 0x46, 0x54, 0xa9, 0x7d, 0xa5, 0xa8, 0x6f, 0x02, 0x1b, 0xbb, + 0x8c, 0xf0, 0x33, 0xe9, 0x65, 0x97, 0x24, 0xa4, 0x23, 0x3c, 0x7a, 0xd0, 0xa5, 0x22, 0xb5, 0x9f, + 0xa3, 0xc9, 0x73, 0xa7, 0x22, 0xe6, 0x4c, 0x50, 0xfc, 0x10, 0x15, 0x63, 0x38, 0xa9, 0x18, 0xb3, + 0x46, 0x6d, 0xa2, 0x61, 0x39, 0x57, 0x57, 0xc5, 0x51, 0xbc, 0x0d, 0xf3, 0xf0, 0xf7, 0x4c, 0xce, + 0xd3, 0x1c, 0xfb, 0x6b, 0x1e, 0xdd, 0x52, 0xaa, 0x6d, 0xc2, 0xb2, 0x54, 0x18, 0x23, 0x33, 0xed, + 0xc5, 0x14, 0x14, 0xc7, 0x3d, 0x58, 0xe3, 0xfb, 0xa8, 0xac, 0x15, 0xfd, 0x98, 0xf3, 0xb6, 0x4f, + 0x82, 0x20, 0xa1, 0x42, 0x54, 0xf2, 0x80, 0xc1, 0x3a, 0xb6, 0xcb, 0x79, 0x7b, 0x5d, 0x45, 0xb0, + 0x8b, 0x26, 0x53, 0xe8, 0x02, 0xdc, 0xbb, 0x4f, 0x18, 0x53, 0x84, 0x81, 0x50, 0x46, 0x58, 0x42, + 0x58, 0xa4, 0xe4, 0xa5, 0x4c, 0xd1, 0xe2, 0x11, 0xf3, 0x03, 0xca, 0x78, 0xa7, 0x62, 0x02, 0xbe, + 0xa4, 0x23, 0x9b, 0x3c, 0x62, 0x5b, 0xf2, 0x1c, 0x5b, 0x08, 0x65, 0x1a, 0x34, 0xa8, 0x14, 0x00, + 0x35, 0x70, 0x82, 0x1f, 0x23, 0x74, 0xd6, 0xc3, 0x4a, 0x11, 0x8a, 0x33, 0x97, 0x15, 0x47, 0x36, + 0xdc, 0x51, 0xb3, 0x74, 0x56, 0x9f, 0x90, 0xea, 0x02, 0x78, 0x03, 0x4c, 0xfb, 0x8b, 0x91, 0xb5, + 0x43, 0x95, 0x48, 0xd7, 0x7d, 0x0d, 0x15, 0x62, 0x79, 0x50, 0x31, 0x66, 0xc7, 0x6a, 0x13, 0x8d, + 0xb2, 0xa3, 0xba, 0xed, 0x64, 0x83, 0xe0, 0xac, 0xb3, 0xde, 0xc6, 0xf8, 0x8f, 0xef, 0xcb, 0x05, + 0xc9, 0xdb, 0xf1, 0x14, 0x1a, 0x6f, 0x9f, 0x73, 0x95, 0x07, 0x57, 0xf3, 0xd7, 0xba, 0x52, 0x39, + 0xcf, 0xd9, 0x5a, 0x44, 0xa5, 0xbe, 0xab, 0xac, 0x6f, 0x77, 0xd0, 0x7f, 0x32, 0x8b, 0x1f, 0x05, + 0xd0, 0x3a, 0xd3, 0x2b, 0xca, 0xed, 0x4e, 0x60, 0x3f, 0x19, 0xe8, 0x72, 0xff, 0x06, 0xab, 0xc8, + 0x94, 0x61, 0x3d, 0x37, 0xd7, 0x5e, 0x00, 0xc0, 0xb6, 0x85, 0xa6, 0x40, 0x69, 0xb3, 0x9b, 0x24, + 0x94, 0xa5, 0x8f, 0x62, 0xde, 0xda, 0xdf, 0x22, 0xbd, 0xfe, 0x94, 0x3e, 0x45, 0xd3, 0x43, 0xe2, + 0x3a, 0xeb, 0x12, 0xc2, 0x2d, 0x15, 0xf3, 0xa9, 0x0c, 0xfa, 0x01, 0xe9, 0xa9, 0xd9, 0xfd, 0xdf, + 0x2b, 0xb5, 0x2e, 0xb0, 0x1a, 0xc7, 0x26, 0x2a, 0x80, 0x1e, 0xfe, 0x60, 0xa0, 0xa2, 0x1a, 0x61, + 0x5c, 0x1f, 0x36, 0xe2, 0x97, 0x5f, 0x4d, 0x75, 0xf1, 0x46, 0x58, 0xe5, 0xcd, 0x9e, 0x7b, 0xf7, + 0xf3, 0xcf, 0xe7, 0xfc, 0x2c, 0xb6, 0xf4, 0x7b, 0xbc, 0xf4, 0xf5, 0x50, 0xaf, 0x06, 0xbf, 0x37, + 0x10, 0x14, 0x45, 0xe0, 0x85, 0xd1, 0xf2, 0x03, 0x8f, 0xaa, 0x5a, 0xbf, 0x09, 0x54, 0x1b, 0xb9, + 0x07, 0x46, 0x66, 0xf0, 0xf4, 0x50, 0x23, 0x90, 0xfd, 0xa3, 0x81, 0x4c, 0x49, 0xc4, 0xb5, 0x6b, + 0xb5, 0x33, 0x17, 0x0b, 0x37, 0x40, 0x6a, 0x13, 0x2e, 0x98, 0x58, 0xc0, 0xf3, 0x23, 0x4d, 0xb8, + 0x6f, 0xf4, 0xc8, 0xbd, 0xc5, 0xdf, 0x0c, 0x54, 0xba, 0xd8, 0x77, 0xfc, 0x60, 0x64, 0xc2, 0x21, + 0x63, 0x54, 0x5d, 0xfb, 0x47, 0x96, 0xb6, 0xdc, 0x00, 0xcb, 0x4b, 0xb8, 0x3e, 0xcc, 0xf2, 0xe5, + 0xd1, 0xdb, 0xd8, 0x3e, 0x3c, 0xb1, 0x8c, 0xa3, 0x13, 0xcb, 0x38, 0x3e, 0xb1, 0x8c, 0x4f, 0xa7, + 0x56, 0xee, 0xe8, 0xd4, 0xca, 0xfd, 0x3a, 0xb5, 0x72, 0x2f, 0x96, 0xc3, 0x28, 0xdd, 0xef, 0x36, + 0x9d, 0x16, 0xef, 0xb8, 0x57, 0xfc, 0xa5, 0xbc, 0xee, 0xaf, 0xe4, 0x07, 0x52, 0x34, 0x8b, 0xf0, + 0x72, 0x56, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x97, 0x71, 0xeb, 0x8b, 0xbf, 0x06, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -416,6 +505,8 @@ type QueryClient interface { Plans(ctx context.Context, in *QueryPlansRequest, opts ...grpc.CallOption) (*QueryPlansResponse, error) // Plan returns a specific plan. Plan(ctx context.Context, in *QueryPlanRequest, opts ...grpc.CallOption) (*QueryPlanResponse, error) + // CurrentEpochDays returns current epoch days. + CurrentEpochDays(ctx context.Context, in *QueryCurrentEpochDaysRequest, opts ...grpc.CallOption) (*QueryCurrentEpochDaysResponse, error) } type queryClient struct { @@ -453,6 +544,15 @@ func (c *queryClient) Plan(ctx context.Context, in *QueryPlanRequest, opts ...gr return out, nil } +func (c *queryClient) CurrentEpochDays(ctx context.Context, in *QueryCurrentEpochDaysRequest, opts ...grpc.CallOption) (*QueryCurrentEpochDaysResponse, error) { + out := new(QueryCurrentEpochDaysResponse) + err := c.cc.Invoke(ctx, "/cosmos.farming.v1beta1.Query/CurrentEpochDays", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // QueryServer is the server API for Query service. type QueryServer interface { // Params returns parameters of the farming module. @@ -461,6 +561,8 @@ type QueryServer interface { Plans(context.Context, *QueryPlansRequest) (*QueryPlansResponse, error) // Plan returns a specific plan. Plan(context.Context, *QueryPlanRequest) (*QueryPlanResponse, error) + // CurrentEpochDays returns current epoch days. + CurrentEpochDays(context.Context, *QueryCurrentEpochDaysRequest) (*QueryCurrentEpochDaysResponse, error) } // UnimplementedQueryServer can be embedded to have forward compatible implementations. @@ -476,6 +578,9 @@ func (*UnimplementedQueryServer) Plans(ctx context.Context, req *QueryPlansReque func (*UnimplementedQueryServer) Plan(ctx context.Context, req *QueryPlanRequest) (*QueryPlanResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Plan not implemented") } +func (*UnimplementedQueryServer) CurrentEpochDays(ctx context.Context, req *QueryCurrentEpochDaysRequest) (*QueryCurrentEpochDaysResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CurrentEpochDays not implemented") +} func RegisterQueryServer(s grpc1.Server, srv QueryServer) { s.RegisterService(&_Query_serviceDesc, srv) @@ -535,6 +640,24 @@ func _Query_Plan_Handler(srv interface{}, ctx context.Context, dec func(interfac return interceptor(ctx, in, info, handler) } +func _Query_CurrentEpochDays_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryCurrentEpochDaysRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryServer).CurrentEpochDays(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cosmos.farming.v1beta1.Query/CurrentEpochDays", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryServer).CurrentEpochDays(ctx, req.(*QueryCurrentEpochDaysRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Query_serviceDesc = grpc.ServiceDesc{ ServiceName: "cosmos.farming.v1beta1.Query", HandlerType: (*QueryServer)(nil), @@ -551,6 +674,10 @@ var _Query_serviceDesc = grpc.ServiceDesc{ MethodName: "Plan", Handler: _Query_Plan_Handler, }, + { + MethodName: "CurrentEpochDays", + Handler: _Query_CurrentEpochDays_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "tendermint/farming/v1beta1/query.proto", @@ -794,6 +921,57 @@ func (m *QueryPlanResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *QueryCurrentEpochDaysRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryCurrentEpochDaysRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryCurrentEpochDaysRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + return len(dAtA) - i, nil +} + +func (m *QueryCurrentEpochDaysResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryCurrentEpochDaysResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryCurrentEpochDaysResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.CurrentEpochDays != 0 { + i = encodeVarintQuery(dAtA, i, uint64(m.CurrentEpochDays)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func encodeVarintQuery(dAtA []byte, offset int, v uint64) int { offset -= sovQuery(v) base := offset @@ -902,6 +1080,27 @@ func (m *QueryPlanResponse) Size() (n int) { return n } +func (m *QueryCurrentEpochDaysRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + return n +} + +func (m *QueryCurrentEpochDaysResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.CurrentEpochDays != 0 { + n += 1 + sovQuery(uint64(m.CurrentEpochDays)) + } + return n +} + func sovQuery(x uint64) (n int) { return (math_bits.Len64(x|1) + 6) / 7 } @@ -1562,6 +1761,125 @@ func (m *QueryPlanResponse) Unmarshal(dAtA []byte) error { } return nil } +func (m *QueryCurrentEpochDaysRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryCurrentEpochDaysRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryCurrentEpochDaysRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryCurrentEpochDaysResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryCurrentEpochDaysResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryCurrentEpochDaysResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CurrentEpochDays", wireType) + } + m.CurrentEpochDays = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQuery + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CurrentEpochDays |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipQuery(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQuery + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipQuery(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 diff --git a/x/farming/types/query.pb.gw.go b/x/farming/types/query.pb.gw.go index 1dba8329..a2eb3329 100644 --- a/x/farming/types/query.pb.gw.go +++ b/x/farming/types/query.pb.gw.go @@ -139,6 +139,24 @@ func local_request_Query_Plan_0(ctx context.Context, marshaler runtime.Marshaler } +func request_Query_CurrentEpochDays_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryCurrentEpochDaysRequest + var metadata runtime.ServerMetadata + + msg, err := client.CurrentEpochDays(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_Query_CurrentEpochDays_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryCurrentEpochDaysRequest + var metadata runtime.ServerMetadata + + msg, err := server.CurrentEpochDays(ctx, &protoReq) + return msg, metadata, err + +} + // RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // UnaryRPC :call QueryServer directly. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. @@ -205,6 +223,26 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv }) + mux.Handle("GET", pattern_Query_CurrentEpochDays_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_Query_CurrentEpochDays_0(rctx, inboundMarshaler, server, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_CurrentEpochDays_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -306,6 +344,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie }) + mux.Handle("GET", pattern_Query_CurrentEpochDays_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Query_CurrentEpochDays_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Query_CurrentEpochDays_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -315,6 +373,8 @@ var ( pattern_Query_Plans_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "farming", "v1beta1", "plans"}, "", runtime.AssumeColonVerbOpt(false))) pattern_Query_Plan_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"cosmos", "farming", "v1beta1", "plans", "plan_id"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_Query_CurrentEpochDays_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"cosmos", "farming", "v1beta1", "current_epoch_days"}, "", runtime.AssumeColonVerbOpt(false))) ) var ( @@ -323,4 +383,6 @@ var ( forward_Query_Plans_0 = runtime.ForwardResponseMessage forward_Query_Plan_0 = runtime.ForwardResponseMessage + + forward_Query_CurrentEpochDays_0 = runtime.ForwardResponseMessage ) From 83bfd7e64314536072d1e69ef46821bf77cb8750 Mon Sep 17 00:00:00 2001 From: kogisin Date: Thu, 16 Sep 2021 19:52:06 +0900 Subject: [PATCH 18/20] fix: apply code review feedbacks and suggestions --- proto/tendermint/farming/v1beta1/farming.proto | 2 +- x/farming/keeper/msg_server.go | 2 -- x/farming/spec/03_state_transitions.md | 8 ++++---- x/farming/types/farming.pb.go | 2 +- x/farming/types/genesis.go | 2 +- x/farming/types/genesis_test.go | 2 +- x/farming/types/params.go | 9 +++++---- x/farming/types/params_test.go | 4 ++-- 8 files changed, 15 insertions(+), 16 deletions(-) diff --git a/proto/tendermint/farming/v1beta1/farming.proto b/proto/tendermint/farming/v1beta1/farming.proto index dc3306d6..1c990b41 100644 --- a/proto/tendermint/farming/v1beta1/farming.proto +++ b/proto/tendermint/farming/v1beta1/farming.proto @@ -23,7 +23,7 @@ message Params { ]; // next_epoch_days is the epoch length in number of days - // it updates internal parameter called CurrentEpochDays that is used to process + // it updates internal state called CurrentEpochDays that is used to process // staking and reward distribution in end blocker uint32 next_epoch_days = 2 [(gogoproto.moretags) = "yaml:\"next_epoch_days\""]; diff --git a/x/farming/keeper/msg_server.go b/x/farming/keeper/msg_server.go index 491c45c1..61a1fd2e 100644 --- a/x/farming/keeper/msg_server.go +++ b/x/farming/keeper/msg_server.go @@ -7,7 +7,6 @@ package keeper import ( "context" - "fmt" sdk "github.com/cosmos/cosmos-sdk/types" @@ -39,7 +38,6 @@ func (k msgServer) CreateFixedAmountPlan(goCtx context.Context, msg *types.MsgCr } plans := k.GetAllPlans(ctx) - fmt.Println("plans: ", len(plans)) if err := types.ValidateName(plans); err != nil { return nil, err } diff --git a/x/farming/spec/03_state_transitions.md b/x/farming/spec/03_state_transitions.md index 1d5db5d1..e784ef7d 100644 --- a/x/farming/spec/03_state_transitions.md +++ b/x/farming/spec/03_state_transitions.md @@ -31,11 +31,11 @@ const ( - Each `farmingPlan` has its own `startTime` and `endTime` - Distribution Method - `FixedAmountPlan` - - fixed amount of coins are distributed for each `NextEpochDays` - - amount in `sdk.Coins` + - fixed amount of coins are distributed per `CurrentEpochDays` + - `epochAmount` is `sdk.Coins` - `RatioPlan` - - `epochRatio` of total assets in `farmingPoolAddress` is distributed for each `NextEpochDays` - - `epochRatio` in percentage + - ratio of total assets in `farmingPoolAddress` is distributed per `CurrentEpochDays` + - `epochRatio` is in percentage - Termination Address - When the plan ends after the `endTime`, transfer the balance of `farmingPoolAddress` to `terminationAddress`. diff --git a/x/farming/types/farming.pb.go b/x/farming/types/farming.pb.go index dabeb441..7b02a62a 100644 --- a/x/farming/types/farming.pb.go +++ b/x/farming/types/farming.pb.go @@ -68,7 +68,7 @@ type Params struct { // this fee prevents from spamming and it is collected in the community pool PrivatePlanCreationFee github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,1,rep,name=private_plan_creation_fee,json=privatePlanCreationFee,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"private_plan_creation_fee" yaml:"private_plan_creation_fee"` // next_epoch_days is the epoch length in number of days - // it updates internal parameter called CurrentEpochDays that is used to process + // it updates internal state called CurrentEpochDays that is used to process // staking and reward distribution in end blocker NextEpochDays uint32 `protobuf:"varint,2,opt,name=next_epoch_days,json=nextEpochDays,proto3" json:"next_epoch_days,omitempty" yaml:"next_epoch_days"` // farming_fee_collector is the module account address to collect fees within the farming module diff --git a/x/farming/types/genesis.go b/x/farming/types/genesis.go index 5c483882..51b08486 100644 --- a/x/farming/types/genesis.go +++ b/x/farming/types/genesis.go @@ -39,7 +39,7 @@ func DefaultGenesisState() *GenesisState { sdk.Coins{}, sdk.Coins{}, time.Time{}, - 1, + DefaultCurrentEpochDays, ) } diff --git a/x/farming/types/genesis_test.go b/x/farming/types/genesis_test.go index ee050f83..56644b83 100644 --- a/x/farming/types/genesis_test.go +++ b/x/farming/types/genesis_test.go @@ -29,7 +29,7 @@ func TestValidateGenesis(t *testing.T) { params.NextEpochDays = 0 genState.Params = params }, - "epoch days must be positive: 0", + "next epoch days must be positive: 0", }, } for _, tc := range testCases { diff --git a/x/farming/types/params.go b/x/farming/types/params.go index 7fd5f4dc..07d9be8d 100644 --- a/x/farming/types/params.go +++ b/x/farming/types/params.go @@ -17,6 +17,7 @@ var ( KeyFarmingFeeCollector = []byte("FarmingFeeCollector") DefaultPrivatePlanCreationFee = sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(100_000_000))) + DefaultCurrentEpochDays = uint32(1) DefaultNextEpochDays = uint32(1) DefaultFarmingFeeCollector = sdk.AccAddress(address.Module(ModuleName, []byte("FarmingFeeCollectorAcc"))).String() StakingReserveAcc = sdk.AccAddress(address.Module(ModuleName, []byte("StakingReserveAcc"))) @@ -43,7 +44,7 @@ func DefaultParams() Params { func (p *Params) ParamSetPairs() paramstypes.ParamSetPairs { return paramstypes.ParamSetPairs{ paramstypes.NewParamSetPair(KeyPrivatePlanCreationFee, &p.PrivatePlanCreationFee, validatePrivatePlanCreationFee), - paramstypes.NewParamSetPair(KeyNextEpochDays, &p.NextEpochDays, validateEpochDays), + paramstypes.NewParamSetPair(KeyNextEpochDays, &p.NextEpochDays, validateNextEpochDays), paramstypes.NewParamSetPair(KeyFarmingFeeCollector, &p.FarmingFeeCollector, validateFarmingFeeCollector), } } @@ -61,7 +62,7 @@ func (p Params) Validate() error { validator func(interface{}) error }{ {p.PrivatePlanCreationFee, validatePrivatePlanCreationFee}, - {p.NextEpochDays, validateEpochDays}, + {p.NextEpochDays, validateNextEpochDays}, {p.FarmingFeeCollector, validateFarmingFeeCollector}, } { if err := v.validator(v.value); err != nil { @@ -84,14 +85,14 @@ func validatePrivatePlanCreationFee(i interface{}) error { return nil } -func validateEpochDays(i interface{}) error { +func validateNextEpochDays(i interface{}) error { v, ok := i.(uint32) if !ok { return fmt.Errorf("invalid parameter type: %T", i) } if v <= 0 { - return fmt.Errorf("epoch days must be positive: %d", v) + return fmt.Errorf("next epoch days must be positive: %d", v) } return nil diff --git a/x/farming/types/params_test.go b/x/farming/types/params_test.go index 9912a5d1..7a8807fe 100644 --- a/x/farming/types/params_test.go +++ b/x/farming/types/params_test.go @@ -42,11 +42,11 @@ func TestParamsValidate(t *testing.T) { "", }, { - "NegativeEpochDays", + "ZeroNextEpochDays", func(params *types.Params) { params.NextEpochDays = uint32(0) }, - "epoch days must be positive: 0", + "next epoch days must be positive: 0", }, { "EmptyFarmingFeeCollector", From e9b77aa5a58465329a6d489688eaf873a5182a70 Mon Sep 17 00:00:00 2001 From: kogisin Date: Thu, 16 Sep 2021 19:59:56 +0900 Subject: [PATCH 19/20] fix: resolve conflicts --- x/farming/client/cli/flags.go | 16 ++++ x/farming/client/cli/query.go | 147 +++++++++++++++++++++++++++++++++- 2 files changed, 160 insertions(+), 3 deletions(-) diff --git a/x/farming/client/cli/flags.go b/x/farming/client/cli/flags.go index 209c71ef..5ce509d7 100644 --- a/x/farming/client/cli/flags.go +++ b/x/farming/client/cli/flags.go @@ -26,6 +26,22 @@ func flagSetPlans() *flag.FlagSet { return fs } +func flagSetStakings() *flag.FlagSet { + fs := flag.NewFlagSet("", flag.ContinueOnError) + + fs.String(FlagStakingCoinDenom, "", "The staking coin denom") + + return fs +} + +func flagSetRewards() *flag.FlagSet { + fs := flag.NewFlagSet("", flag.ContinueOnError) + + fs.String(FlagStakingCoinDenom, "", "The staking coin denom") + + return fs +} + func flagSetHarvest() *flag.FlagSet { fs := flag.NewFlagSet("", flag.ContinueOnError) diff --git a/x/farming/client/cli/query.go b/x/farming/client/cli/query.go index 6466fbd1..102428d8 100644 --- a/x/farming/client/cli/query.go +++ b/x/farming/client/cli/query.go @@ -34,6 +34,9 @@ func GetQueryCmd() *cobra.Command { GetCmdQueryParams(), GetCmdQueryPlans(), GetCmdQueryPlan(), + GetCmdQueryStakings(), + GetCmdQueryTotalStakings(), + GetCmdQueryRewards(), GetCmdQueryCurrentEpochDays(), ) @@ -47,7 +50,6 @@ func GetCmdQueryParams() *cobra.Command { Short: "Query the current farming parameters information", Long: strings.TrimSpace( fmt.Sprintf(`Query values set as farming parameters. - Example: $ %s query %s params `, @@ -83,7 +85,6 @@ func GetCmdQueryPlans() *cobra.Command { Short: "Query for all plans", Long: strings.TrimSpace( fmt.Sprintf(`Query details about all farming plans on a network. - Example: $ %s query %s plans $ %s query %s plans --plan-type private @@ -154,7 +155,6 @@ func GetCmdQueryPlan() *cobra.Command { Short: "Query a specific plan", Long: strings.TrimSpace( fmt.Sprintf(`Query details about a specific plan. - Example: $ %s query %s plan `, @@ -190,6 +190,147 @@ $ %s query %s plan return cmd } +func GetCmdQueryStakings() *cobra.Command { + bech32PrefixAccAddr := sdk.GetConfig().GetBech32AccountAddrPrefix() + + cmd := &cobra.Command{ + Use: "stakings [farmer]", + Args: cobra.ExactArgs(1), + Short: "Query stakings by a farmer", + Long: strings.TrimSpace( + fmt.Sprintf(`Query all stakings by a farmer. +Optionally restrict coins for a staking coin denom. +Example: +$ %s query %s stakings %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj +$ %s query %s stakings %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj --staking-coin-denom poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4 +`, + version.AppName, types.ModuleName, bech32PrefixAccAddr, + version.AppName, types.ModuleName, bech32PrefixAccAddr, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + farmerAcc, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + stakingCoinDenom, _ := cmd.Flags().GetString(FlagStakingCoinDenom) + + resp, err := queryClient.Stakings(cmd.Context(), &types.QueryStakingsRequest{ + Farmer: farmerAcc.String(), + StakingCoinDenom: stakingCoinDenom, + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(resp) + }, + } + + cmd.Flags().AddFlagSet(flagSetStakings()) + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func GetCmdQueryTotalStakings() *cobra.Command { + cmd := &cobra.Command{ + Use: "total-stakings [staking-coin-denom]", + Args: cobra.ExactArgs(1), + Short: "Query total staking amount for a staking coin denom", + Long: strings.TrimSpace( + fmt.Sprintf(`Query total staking amount for a staking coin denom. +Example: +$ %s query %s total-stakings poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4 +`, + version.AppName, types.ModuleName, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + stakingCoinDenom := args[0] + if err := sdk.ValidateDenom(stakingCoinDenom); err != nil { + return err + } + + resp, err := queryClient.TotalStakings(cmd.Context(), &types.QueryTotalStakingsRequest{ + StakingCoinDenom: stakingCoinDenom, + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(resp) + }, + } + + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + +func GetCmdQueryRewards() *cobra.Command { + bech32PrefixAccAddr := sdk.GetConfig().GetBech32AccountAddrPrefix() + + cmd := &cobra.Command{ + Use: "rewards [farmer]", + Args: cobra.ExactArgs(1), + Short: "Query rewards for a farmer", + Long: strings.TrimSpace( + fmt.Sprintf(`Query all rewards for a farmer. +Optionally restrict rewards for a staking coin denom. +Example: +$ %s query %s rewards %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj +$ %s query %s rewards %s1gghjut3ccd8ay0zduzj64hwre2fxs9ldmqhffj --staking-coin-denom poolD35A0CC16EE598F90B044CE296A405BA9C381E38837599D96F2F70C2F02A23A4 +`, + version.AppName, types.ModuleName, bech32PrefixAccAddr, + version.AppName, types.ModuleName, bech32PrefixAccAddr, + ), + ), + RunE: func(cmd *cobra.Command, args []string) error { + clientCtx, err := client.GetClientQueryContext(cmd) + if err != nil { + return err + } + queryClient := types.NewQueryClient(clientCtx) + + farmerAcc, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + stakingCoinDenom, _ := cmd.Flags().GetString(FlagStakingCoinDenom) + + resp, err := queryClient.Rewards(cmd.Context(), &types.QueryRewardsRequest{ + Farmer: farmerAcc.String(), + StakingCoinDenom: stakingCoinDenom, + }) + if err != nil { + return err + } + + return clientCtx.PrintProto(resp) + }, + } + + cmd.Flags().AddFlagSet(flagSetRewards()) + flags.AddQueryFlagsToCmd(cmd) + + return cmd +} + func GetCmdQueryCurrentEpochDays() *cobra.Command { cmd := &cobra.Command{ Use: "current-epoch-days", From 33b41adceb9bcc5836202bcabdd73c95dd2ed9f6 Mon Sep 17 00:00:00 2001 From: kogisin Date: Thu, 16 Sep 2021 20:58:19 +0900 Subject: [PATCH 20/20] fix: panic when unstake due to total stakings is not set --- x/farming/client/cli/cli_test.go | 4 ++-- x/farming/keeper/staking.go | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/x/farming/client/cli/cli_test.go b/x/farming/client/cli/cli_test.go index 2d44afcd..a8bb7e5c 100644 --- a/x/farming/client/cli/cli_test.go +++ b/x/farming/client/cli/cli_test.go @@ -1,3 +1,5 @@ +// +build norace + package cli_test import ( @@ -20,8 +22,6 @@ import ( farmingtypes "github.com/tendermint/farming/x/farming/types" ) -// // +build norace - type IntegrationTestSuite struct { suite.Suite diff --git a/x/farming/keeper/staking.go b/x/farming/keeper/staking.go index 7cd91ac1..985ee248 100644 --- a/x/farming/keeper/staking.go +++ b/x/farming/keeper/staking.go @@ -264,7 +264,9 @@ func (k Keeper) Unstake(ctx sdk.Context, farmerAcc sdk.AccAddress, amount sdk.Co k.DeleteQueuedStaking(ctx, coin.Denom, farmerAcc) } - k.DecreaseTotalStakings(ctx, coin.Denom, removedFromStaking) + if removedFromStaking.IsPositive() { + k.DecreaseTotalStakings(ctx, coin.Denom, removedFromStaking) + } } if err := k.ReleaseStakingCoins(ctx, farmerAcc, amount); err != nil {