diff --git a/go.mod b/go.mod index b0f6d7a8..5e39708d 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/tendermint/go-amino v0.15.0 github.com/tendermint/tendermint v0.32.5 github.com/tendermint/tm-db v0.2.0 - gopkg.in/yaml.v2 v2.2.3 + gopkg.in/yaml.v2 v2.2.4 ) replace github.com/cosmos/cosmos-sdk => ../../cosmos/cosmos-sdk diff --git a/go.sum b/go.sum index 0154b17c..2b1c40e9 100644 --- a/go.sum +++ b/go.sum @@ -170,6 +170,8 @@ github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= +github.com/pelletier/go-toml v1.5.0 h1:5BakdOZdtKJ1FFk6QdL8iSGrMWsXgchNJcrnarjbmJQ= +github.com/pelletier/go-toml v1.5.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -338,5 +340,7 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/x/validator-vesting/internal/keeper/keeper.go b/x/validator-vesting/internal/keeper/keeper.go index dd7e380c..bce5603b 100644 --- a/x/validator-vesting/internal/keeper/keeper.go +++ b/x/validator-vesting/internal/keeper/keeper.go @@ -120,16 +120,30 @@ func (k Keeper) UpdateVestedCoinsProgress(ctx sdk.Context, addr sdk.AccAddress, } if successfulVest { - vv.VestingPeriodProgress[period].VestingSuccessful = true + k.SetVestingProgress(ctx, addr, period, true) } else { - vv.VestingPeriodProgress[period].VestingSuccessful = false - notVestedTokens := vv.VestingPeriods[period].Amount - // add the tokens that did not vest to DebtAfterFailedVesting - vv.DebtAfterFailedVesting = vv.DebtAfterFailedVesting.Add(notVestedTokens) + k.SetVestingProgress(ctx, addr, period, false) + k.AddDebt(ctx, addr, vv.VestingPeriods[period].Amount) } - vv.VestingPeriodProgress[period].PeriodComplete = true - // reset the number of missed blocks and total number of blocks in the period to zero - vv.CurrentPeriodProgress = types.CurrentPeriodProgress{0, 0} + k.ResetCurrentPeriodProgress(ctx, addr) +} + +// SetVestingProgress sets VestingPeriodProgress for the input period +func (k Keeper) SetVestingProgress(ctx sdk.Context, addr sdk.AccAddress, period int, success bool) { + vv := k.GetAccountFromAuthKeeper(ctx, addr) + vv.VestingPeriodProgress[period] = types.VestingProgress{PeriodComplete: true, VestingSuccessful: success} + k.ak.SetAccount(ctx, vv) +} + +func (k Keeper) AddDebt(ctx sdk.Context, addr sdk.AccAddress, amount sdk.Coins) { + vv := k.GetAccountFromAuthKeeper(ctx, addr) + vv.DebtAfterFailedVesting = vv.DebtAfterFailedVesting.Add(amount) + k.ak.SetAccount(ctx, vv) +} + +func (k Keeper) ResetCurrentPeriodProgress(ctx sdk.Context, addr sdk.AccAddress) { + vv := k.GetAccountFromAuthKeeper(ctx, addr) + vv.CurrentPeriodProgress = types.CurrentPeriodProgress{TotalBlocks: 0, MissedBlocks: 0} k.ak.SetAccount(ctx, vv) } @@ -138,8 +152,8 @@ func (k Keeper) UpdateVestedCoinsProgress(ctx sdk.Context, addr sdk.AccAddress, // otherwise unbonds all existing tokens. func (k Keeper) HandleVestingDebt(ctx sdk.Context, addr sdk.AccAddress, blockTime time.Time) { vv := k.GetAccountFromAuthKeeper(ctx, addr) - remainingDebt := !vv.DebtAfterFailedVesting.IsZero() - if remainingDebt { + + if !vv.DebtAfterFailedVesting.IsZero() { spendableCoins := vv.SpendableCoins(blockTime) if spendableCoins.IsAllGTE(vv.DebtAfterFailedVesting) { if vv.ReturnAddress != nil { @@ -157,9 +171,7 @@ func (k Keeper) HandleVestingDebt(ctx sdk.Context, addr sdk.AccAddress, blockTim panic(err) } } - vv = k.GetAccountFromAuthKeeper(ctx, addr) - vv.DebtAfterFailedVesting = sdk.NewCoins() - k.ak.SetAccount(ctx, vv) + k.ResetDebt(ctx, addr) } else { // iterate over all delegations made from the validator vesting account and undelegate // note that we cannot safely undelegate only an amount of shares that covers the debt, @@ -172,6 +184,13 @@ func (k Keeper) HandleVestingDebt(ctx sdk.Context, addr sdk.AccAddress, blockTim } } +// ResetDebt sets DebtAfterFailedVesting to zero +func (k Keeper) ResetDebt(ctx sdk.Context, addr sdk.AccAddress) { + vv := k.GetAccountFromAuthKeeper(ctx, addr) + vv.DebtAfterFailedVesting = sdk.NewCoins() + k.ak.SetAccount(ctx, vv) +} + // GetPeriodEndTimes returns an array of the times when each period ends func (k Keeper) GetPeriodEndTimes(ctx sdk.Context, addr sdk.AccAddress) []int64 { var endTimes []int64 diff --git a/x/validator-vesting/internal/types/validator_vesting_account.go b/x/validator-vesting/internal/types/validator_vesting_account.go index bf7cce24..27d7bde1 100644 --- a/x/validator-vesting/internal/types/validator_vesting_account.go +++ b/x/validator-vesting/internal/types/validator_vesting_account.go @@ -23,16 +23,19 @@ func init() { authtypes.RegisterAccountTypeCodec(&ValidatorVestingAccount{}, "cosmos-sdk/ValidatorVestingAccount") } +// VestingProgress tracks the status of each vesting period type VestingProgress struct { PeriodComplete bool `json:"period_complete" yaml:"period_complete"` VestingSuccessful bool `json:"vesting_successful" yaml:"vesting_successful"` } +// CurrentPeriodProgress tracks the progress of the current vesting period type CurrentPeriodProgress struct { MissedBlocks int64 `json:"missed_blocks" yaml:"missed_blocks"` TotalBlocks int64 `json:"total_blocks" yaml:"total_blocks` } +// GetSignedPercentage returns the percentage of blocks signed for the current vesting period func (cpp CurrentPeriodProgress) GetSignedPercentage() sdk.Dec { blocksSigned := cpp.TotalBlocks - cpp.MissedBlocks // signed_percentage = blocksSigned/TotalBlocks * 100 @@ -42,6 +45,7 @@ func (cpp CurrentPeriodProgress) GetSignedPercentage() sdk.Dec { return signedPercentage } +// SignedPercetageIsOverThreshold checks if the signed percentage exceeded the threshold func (cpp CurrentPeriodProgress) SignedPercetageIsOverThreshold(threshold int64) bool { signedPercentage := cpp.GetSignedPercentage() return signedPercentage.GTE(sdk.NewDec(threshold)) @@ -169,7 +173,7 @@ func (vva ValidatorVestingAccount) GetVestingCoins(blockTime time.Time) sdk.Coin // SpendableCoins returns the total number of spendable coins per denom for a // periodic vesting account. func (vva ValidatorVestingAccount) SpendableCoins(blockTime time.Time) sdk.Coins { - return vva.BaseVestingAccount.SpendableCoinsFromVestingCoins(vva.GetVestingCoins(blockTime)) + return vva.BaseVestingAccount.SpendableCoinsVestingAccount(vva.GetVestingCoins(blockTime)) } // TrackDelegation tracks a desired delegation amount by setting the appropriate