Skip to content

Commit

Permalink
use concrete time types
Browse files Browse the repository at this point in the history
  • Loading branch information
likhita-809 committed Nov 3, 2023
1 parent e818975 commit 0b4898c
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 49 deletions.
12 changes: 8 additions & 4 deletions x/protocolpool/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package keeper_test

import (
"time"

"cosmossdk.io/x/protocolpool/keeper"
"cosmossdk.io/x/protocolpool/types"

Expand All @@ -9,6 +11,8 @@ import (

func (suite *KeeperTestSuite) TestUnclaimedBudget() {
queryServer := keeper.NewQuerier(suite.poolKeeper)
startTime := suite.ctx.BlockTime().Add(-70 * time.Second)
period := time.Duration(60) * time.Second
testCases := []struct {
name string
preRun func()
Expand Down Expand Up @@ -40,9 +44,9 @@ func (suite *KeeperTestSuite) TestUnclaimedBudget() {
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix() - 70),
StartTime: &startTime,
Tranches: 2,
Period: 60,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
Expand All @@ -60,9 +64,9 @@ func (suite *KeeperTestSuite) TestUnclaimedBudget() {
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix() - 70),
StartTime: &startTime,
Tranches: 2,
Period: 60,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
Expand Down
33 changes: 18 additions & 15 deletions x/protocolpool/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"time"

"cosmossdk.io/collections"
storetypes "cosmossdk.io/core/store"
Expand Down Expand Up @@ -129,15 +130,15 @@ func (k Keeper) getClaimableFunds(ctx context.Context, recipient sdk.AccAddress)
}
}

currentTime := sdkCtx.BlockTime().Unix()
currentTime := sdkCtx.BlockTime()
startTime := budget.StartTime

// Check if the start time is reached
if uint64(currentTime) < startTime {
if currentTime.Before(*startTime) {
return sdk.Coin{}, fmt.Errorf("distribution has not started yet")
}

if budget.NextClaimFrom == 0 {
if budget.NextClaimFrom == nil || budget.NextClaimFrom.IsZero() {
budget.NextClaimFrom = budget.StartTime
}

Expand All @@ -150,31 +151,32 @@ func (k Keeper) getClaimableFunds(ctx context.Context, recipient sdk.AccAddress)
return k.calculateClaimableFunds(ctx, recipient, budget, currentTime)
}

func (k Keeper) calculateClaimableFunds(ctx context.Context, recipient sdk.AccAddress, budget types.Budget, currentTime int64) (amount sdk.Coin, err error) {
func (k Keeper) calculateClaimableFunds(ctx context.Context, recipient sdk.AccAddress, budget types.Budget, currentTime time.Time) (amount sdk.Coin, err error) {
// Calculate the time elapsed since the last claim time
timeElapsed := uint64(currentTime) - budget.NextClaimFrom
timeElapsed := currentTime.Sub(*budget.NextClaimFrom)

// Check the time elapsed has passed period length
if timeElapsed < budget.Period {
if timeElapsed < *budget.Period {
return sdk.Coin{}, fmt.Errorf("budget period has not passed yet")
}

// Calculate how many periods have passed
periodsPassed := timeElapsed / budget.Period
periodsPassed := int64(timeElapsed) / int64(*budget.Period)

// Calculate the amount to distribute for all passed periods
coinsToDistribute := math.NewInt(int64(periodsPassed)).Mul(budget.TotalBudget.Amount.QuoRaw(int64(budget.Tranches)))
coinsToDistribute := math.NewInt(periodsPassed).Mul(budget.TotalBudget.Amount.QuoRaw(int64(budget.Tranches)))
amount = sdk.NewCoin(budget.TotalBudget.Denom, coinsToDistribute)

// update the budget's remaining tranches
budget.TranchesLeft -= periodsPassed
budget.TranchesLeft -= uint64(periodsPassed)

// update the ClaimedAmount
claimedAmount := budget.ClaimedAmount.Add(amount)
budget.ClaimedAmount = &claimedAmount

// Update the last claim time for the budget
budget.NextClaimFrom += budget.Period
nextClaimFrom := budget.NextClaimFrom.Add(*budget.Period)
budget.NextClaimFrom = &nextClaimFrom

k.Logger(ctx).Debug(fmt.Sprintf("Processing budget for recipient: %s. Amount: %s", budget.RecipientAddress, coinsToDistribute.String()))

Expand All @@ -195,20 +197,21 @@ func (k Keeper) validateAndUpdateBudgetProposal(ctx context.Context, bp types.Ms
return fmt.Errorf("invalid budget proposal: %w", err)
}

currentTime := sdk.UnwrapSDKContext(ctx).BlockTime().Unix()
if int64(bp.StartTime) == 0 {
bp.StartTime = uint64(currentTime)
currentTime := sdk.UnwrapSDKContext(ctx).BlockTime()
if bp.StartTime.IsZero() || bp.StartTime == nil {
bp.StartTime = &currentTime
}

if bp.StartTime < uint64(currentTime) {
// if bp.StartTime < uint64(currentTime) {
if currentTime.After(*bp.StartTime) {
return fmt.Errorf("invalid budget proposal: start time cannot be less than the current block time")
}

if bp.Tranches == 0 {
return fmt.Errorf("invalid budget proposal: tranches must be greater than zero")
}

if bp.Period == 0 {
if bp.Period == nil || *bp.Period == 0 {
return fmt.Errorf("invalid budget proposal: period length should be greater than zero")
}

Expand Down
71 changes: 42 additions & 29 deletions x/protocolpool/keeper/msg_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ var (

func (suite *KeeperTestSuite) TestMsgSubmitBudgetProposal() {
invalidCoin := sdk.NewInt64Coin("foo", 0)
startTime := suite.ctx.BlockTime().Add(10 * time.Second)
invalidStartTime := suite.ctx.BlockTime().Add(-15 * time.Second)
period := time.Duration(60) * time.Second
zeroPeriod := time.Duration(0) * time.Second
testCases := map[string]struct {
preRun func()
input *types.MsgSubmitBudgetProposal
Expand All @@ -29,9 +33,9 @@ func (suite *KeeperTestSuite) TestMsgSubmitBudgetProposal() {
Authority: suite.poolKeeper.GetAuthority(),
RecipientAddress: "",
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix()),
StartTime: &startTime,
Tranches: 2,
Period: 60,
Period: &period,
},
expErr: true,
expErrMsg: "empty address string is not allowed",
Expand All @@ -41,9 +45,9 @@ func (suite *KeeperTestSuite) TestMsgSubmitBudgetProposal() {
Authority: "",
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix()),
StartTime: &startTime,
Tranches: 2,
Period: 60,
Period: &period,
},
expErr: true,
expErrMsg: "empty address string is not allowed",
Expand All @@ -53,9 +57,9 @@ func (suite *KeeperTestSuite) TestMsgSubmitBudgetProposal() {
Authority: "invalid_authority",
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix()),
StartTime: &startTime,
Tranches: 2,
Period: 60,
Period: &period,
},
expErr: true,
expErrMsg: "invalid authority",
Expand All @@ -65,9 +69,9 @@ func (suite *KeeperTestSuite) TestMsgSubmitBudgetProposal() {
Authority: suite.poolKeeper.GetAuthority(),
RecipientAddress: recipientAddr.String(),
TotalBudget: &invalidCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix()),
StartTime: &startTime,
Tranches: 2,
Period: 60,
Period: &period,
},
expErr: true,
expErrMsg: "total budget cannot be zero",
Expand All @@ -77,9 +81,9 @@ func (suite *KeeperTestSuite) TestMsgSubmitBudgetProposal() {
Authority: suite.poolKeeper.GetAuthority(),
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix() - 5),
StartTime: &invalidStartTime,
Tranches: 2,
Period: 60,
Period: &period,
},
expErr: true,
expErrMsg: "start time cannot be less than the current block time",
Expand All @@ -89,9 +93,9 @@ func (suite *KeeperTestSuite) TestMsgSubmitBudgetProposal() {
Authority: suite.poolKeeper.GetAuthority(),
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix() + 10),
StartTime: &startTime,
Tranches: 0,
Period: 60,
Period: &period,
},
expErr: true,
expErrMsg: "tranches must be greater than zero",
Expand All @@ -101,9 +105,9 @@ func (suite *KeeperTestSuite) TestMsgSubmitBudgetProposal() {
Authority: suite.poolKeeper.GetAuthority(),
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix() + 10),
StartTime: &startTime,
Tranches: 2,
Period: 0,
Period: &zeroPeriod,
},
expErr: true,
expErrMsg: "period length should be greater than zero",
Expand All @@ -113,16 +117,17 @@ func (suite *KeeperTestSuite) TestMsgSubmitBudgetProposal() {
Authority: suite.poolKeeper.GetAuthority(),
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix() + 10),
StartTime: &startTime,
Tranches: 2,
Period: 60,
Period: &period,
},
expErr: false,
},
}

for name, tc := range testCases {
suite.Run(name, func() {
suite.SetupTest()
if tc.preRun != nil {
tc.preRun()
}
Expand All @@ -138,6 +143,9 @@ func (suite *KeeperTestSuite) TestMsgSubmitBudgetProposal() {
}

func (suite *KeeperTestSuite) TestMsgClaimBudget() {
startTime := suite.ctx.BlockTime().Add(-70 * time.Second)
period := time.Duration(60) * time.Second

testCases := map[string]struct {
preRun func()
recipientAddress sdk.AccAddress
Expand All @@ -157,13 +165,14 @@ func (suite *KeeperTestSuite) TestMsgClaimBudget() {
},
"claiming before start time": {
preRun: func() {
startTime := suite.ctx.BlockTime().Add(3600 * time.Second)
// Prepare the budget proposal with a future start time
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix() + 3600),
StartTime: &startTime,
Tranches: 2,
Period: 60,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
Expand All @@ -174,13 +183,14 @@ func (suite *KeeperTestSuite) TestMsgClaimBudget() {
},
"budget period has not passed": {
preRun: func() {
startTime := suite.ctx.BlockTime().Add(-50 * time.Second)
// Prepare the budget proposal with start time and a short period
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix() - 50),
StartTime: &startTime,
Tranches: 1,
Period: 60,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
Expand All @@ -195,9 +205,9 @@ func (suite *KeeperTestSuite) TestMsgClaimBudget() {
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix() - 70),
StartTime: &startTime,
Tranches: 2,
Period: 60,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
Expand All @@ -212,9 +222,9 @@ func (suite *KeeperTestSuite) TestMsgClaimBudget() {
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix() - 70),
StartTime: &startTime,
Tranches: 2,
Period: 60,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
Expand All @@ -234,13 +244,15 @@ func (suite *KeeperTestSuite) TestMsgClaimBudget() {
"valid double claim attempt": {
preRun: func() {
oneMonthInSeconds := int64(30 * 24 * 60 * 60) // Approximate number of seconds in 1 month
startTimeBeforeMonth := suite.ctx.BlockTime().Add(time.Duration(-oneMonthInSeconds) * time.Second)
oneMonthPeriod := time.Duration(oneMonthInSeconds) * time.Second
// Prepare the budget proposal with valid start time and period of 1 month (in seconds)
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix() - oneMonthInSeconds),
StartTime: &startTimeBeforeMonth,
Tranches: 2,
Period: uint64(oneMonthInSeconds),
Period: &oneMonthPeriod,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
Expand Down Expand Up @@ -269,9 +281,9 @@ func (suite *KeeperTestSuite) TestMsgClaimBudget() {
budget := types.Budget{
RecipientAddress: recipientAddr.String(),
TotalBudget: &fooCoin,
StartTime: uint64(suite.ctx.BlockTime().Unix() - 70),
StartTime: &startTime,
Tranches: 2,
Period: 60,
Period: &period,
}
err := suite.poolKeeper.BudgetProposal.Set(suite.ctx, recipientAddr, budget)
suite.Require().NoError(err)
Expand All @@ -290,7 +302,7 @@ func (suite *KeeperTestSuite) TestMsgClaimBudget() {
Time: newBlockTime,
})

// Claim the funds twitce
// Claim the funds twice
msg = &types.MsgClaimBudget{
RecipientAddress: recipientAddr.String(),
}
Expand All @@ -306,6 +318,7 @@ func (suite *KeeperTestSuite) TestMsgClaimBudget() {

for name, tc := range testCases {
suite.Run(name, func() {
suite.SetupTest()
if tc.preRun != nil {
tc.preRun()
}
Expand Down
4 changes: 3 additions & 1 deletion x/protocolpool/types/msg.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package types

import (
"time"

sdk "github.com/cosmos/cosmos-sdk/types"
)

Expand Down Expand Up @@ -28,7 +30,7 @@ func NewCommunityPoolSpend(amount sdk.Coins, authority, recipient string) *MsgCo
}
}

func NewBudgetProposal(recipient string, totalBudget sdk.Coin, startTime, tranches, period uint64) *Budget {
func NewBudgetProposal(recipient string, totalBudget sdk.Coin, startTime *time.Time, tranches uint64, period *time.Duration) *Budget {
return &Budget{
RecipientAddress: recipient,
TotalBudget: &totalBudget,
Expand Down

0 comments on commit 0b4898c

Please sign in to comment.