0g-chain/migrate/v0_15/account.go
Nick DeLuca 8b54fdafa4
Reset Periodic Vesting Accounts for Kava-8 (#987)
* add auth test data

* add periodic vesting account migration

* assert owned coins are equal and unchanged during migration

* add script for generating test data from a genesis file

* remove commented import

* touch ups

* don't pretty print test data for auth module; update generate script to
use jq -c option

* fix typo in comment, improve clarity of assertions

* add context to migrate auth assertions

* add 180 days check for spendable coins

* asssertion context

* pr feedback - add assertions, touch up assertion msgs, and fix migration test to correctly
type assert pointer
2021-08-12 10:31:58 -05:00

76 lines
2.7 KiB
Go

package v0_15
import (
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting"
)
// MigrateAccount removes old vesting periods from periodic vesting accounts
// and converts any periodic vesting account with zero periods back to a base account
func MigrateAccount(acc authexported.GenesisAccount, genesisTime time.Time) authexported.GenesisAccount {
if vacc, ok := acc.(*vesting.PeriodicVestingAccount); ok {
ResetPeriodicVestingAccount(vacc, genesisTime)
if genesisTime.Unix() >= vacc.EndTime {
return vacc.BaseVestingAccount.BaseAccount
}
return vacc
}
return acc
}
// ResetPeriodicVestingAccount resets a periodic vesting account to a new start time. The account is
// modified in place, and vesting periods before the new start time are removed from the account.
func ResetPeriodicVestingAccount(vacc *vesting.PeriodicVestingAccount, startTime time.Time) {
currentPeriod := vacc.StartTime
newOriginalVesting := sdk.Coins{}
newStartTime := startTime.Unix()
newEndTime := newStartTime
newPeriods := vesting.Periods{}
for _, period := range vacc.VestingPeriods {
currentPeriod := currentPeriod + period.Length
// Periods less than or equal to the newStartTime are still vesting,
// so adjust their length and add them to them to the newPeriods
if newStartTime <= currentPeriod {
period.Length = currentPeriod - newStartTime
newEndTime = newEndTime + period.Length
newOriginalVesting = newOriginalVesting.Add(period.Amount...)
newPeriods = append(newPeriods, period)
}
}
// In order to preserve the spendable amount of the account, we must drop
// the vesting funds if the start and end time are equal.
if newStartTime == newEndTime {
newOriginalVesting = sdk.Coins{}
newPeriods = vesting.Periods{}
}
// If the new original vesting amount is less than the delegated vesting amount, set delegated vesting
// to the new original vesting amount, and add the difference to the delegated free amount
for _, delegatedVestingCoin := range vacc.DelegatedVesting {
newDelegatedVestingCoin := sdk.NewCoin(delegatedVestingCoin.Denom, sdk.MinInt(delegatedVestingCoin.Amount, newOriginalVesting.AmountOf(delegatedVestingCoin.Denom)))
delegationAdjustment := delegatedVestingCoin.Sub(newDelegatedVestingCoin)
if !delegationAdjustment.IsZero() {
vacc.DelegatedVesting = vacc.DelegatedVesting.Sub(sdk.NewCoins(delegationAdjustment))
vacc.DelegatedFree = vacc.DelegatedFree.Add(delegationAdjustment)
}
}
vacc.StartTime = newStartTime
vacc.EndTime = newEndTime
vacc.OriginalVesting = newOriginalVesting
vacc.VestingPeriods = newPeriods
}