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
This commit is contained in:
Nick DeLuca 2021-08-12 10:31:58 -05:00 committed by GitHub
parent 58b3089ecd
commit 8b54fdafa4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 503 additions and 1 deletions

75
migrate/v0_15/account.go Normal file
View File

@ -0,0 +1,75 @@
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
}

View File

@ -0,0 +1,291 @@
package v0_15
import (
"testing"
"time"
sdk "github.com/cosmos/cosmos-sdk/types"
auth "github.com/cosmos/cosmos-sdk/x/auth"
vesting "github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/stretchr/testify/assert"
"github.com/tendermint/tendermint/crypto/secp256k1"
)
func createVestingAccount(balance sdk.Coins, vestingStart time.Time, vestingPeriods vesting.Periods) *vesting.PeriodicVestingAccount {
key := secp256k1.GenPrivKey()
pub := key.PubKey()
addr := sdk.AccAddress(pub.Address())
acc := auth.NewBaseAccount(addr, balance, pub, 1, 1)
return vesting.NewPeriodicVestingAccount(acc, vestingStart.Unix(), vestingPeriods)
}
func TestMigrateAccount_BaseAccount(t *testing.T) {
balance := sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6)))
key := secp256k1.GenPrivKey()
pub := key.PubKey()
addr := sdk.AccAddress(pub.Address())
acc := auth.NewBaseAccount(addr, balance, pub, 1, 1)
accCopy := *acc
migratedAcc := MigrateAccount(&accCopy, time.Now())
assert.Equal(t, acc, migratedAcc, "expected account to be unmodified")
}
func TestMigrateAccount_PeriodicVestingAccount_NoPeriods(t *testing.T) {
balance := sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6)))
key := secp256k1.GenPrivKey()
pub := key.PubKey()
addr := sdk.AccAddress(pub.Address())
acc := auth.NewBaseAccount(addr, balance, pub, 1, 1)
vacc := vesting.NewPeriodicVestingAccount(acc, time.Now().Unix(), vesting.Periods{})
migratedAcc := MigrateAccount(vacc, time.Now())
assert.Equal(t, acc, migratedAcc, "expected base account to be returned")
}
func TestMigrateAccount_PeriodicVestingAccount_Vesting(t *testing.T) {
balance := sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(3e6)))
vestingStartTime := time.Now().Add(-30 * 24 * time.Hour) // 30 days in past
periods := vesting.Periods{
vesting.Period{
Length: 15 * 24 * 60 * 60, // -15 days - vested
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))),
},
vesting.Period{
Length: 45 * 24 * 60 * 60, // +15 days - vesting
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(2e6))),
},
}
vacc := createVestingAccount(balance, vestingStartTime, periods)
genesisTime := vestingStartTime.Add(30 * 24 * time.Hour)
MigrateAccount(vacc, genesisTime)
expectedVestingPeriods := vesting.Periods{
vesting.Period{
Length: 15 * 24 * 60 * 60,
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(2e6))),
},
}
assert.Equal(t, genesisTime.Unix(), vacc.StartTime, "expected vesting start time to equal genesis time")
assert.Equal(t, expectedVestingPeriods, vacc.VestingPeriods, "expected only one vesting period left")
}
func TestResetPeriodVestingAccount_NoVestingPeriods(t *testing.T) {
vestingStartTime := time.Now().Add(-1 * time.Hour)
vacc := createVestingAccount(sdk.Coins{}, vestingStartTime, vesting.Periods{})
newVestingStartTime := vestingStartTime.Add(time.Hour)
spendableBefore := vacc.SpendableCoins(newVestingStartTime)
ResetPeriodicVestingAccount(vacc, newVestingStartTime)
assert.Equal(t, sdk.Coins{}, vacc.OriginalVesting, "expected original vesting to be zero")
assert.Equal(t, newVestingStartTime.Unix(), vacc.StartTime, "expected vesting start time to be updated")
assert.Equal(t, newVestingStartTime.Unix(), vacc.EndTime, "expected vesting end time to be updated")
assert.Equal(t, vesting.Periods{}, vacc.VestingPeriods, "expected vesting periods to be empty")
assert.Equal(t, spendableBefore, vacc.SpendableCoins(newVestingStartTime), "expected spendable coins to be unchanged")
}
func TestResetPeriodVestingAccount_SingleVestingPeriod_Vested(t *testing.T) {
balance := sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6)))
vestingStartTime := time.Now().Add(-30 * 24 * time.Hour) // 30 days in past
periods := vesting.Periods{
vesting.Period{
Length: 15 * 24 * 60 * 60, // 15 days (-15 days in past)
Amount: balance,
},
}
vacc := createVestingAccount(balance, vestingStartTime, periods)
newVestingStartTime := vestingStartTime.Add(30 * 24 * time.Hour)
spendableBefore := vacc.SpendableCoins(newVestingStartTime)
ResetPeriodicVestingAccount(vacc, newVestingStartTime)
assert.Equal(t, sdk.Coins{}, vacc.OriginalVesting, "expected original vesting to be zero")
assert.Equal(t, newVestingStartTime.Unix(), vacc.StartTime, "expected vesting start time to be updated")
assert.Equal(t, newVestingStartTime.Unix(), vacc.EndTime, "expected vesting end time to be updated")
assert.Equal(t, vesting.Periods{}, vacc.VestingPeriods, "expected vesting periods to be empty")
assert.Equal(t, spendableBefore, vacc.SpendableCoins(newVestingStartTime), "expected spendable coins to be unchanged")
}
func TestResetPeriodVestingAccount_SingleVestingPeriod_Vesting(t *testing.T) {
balance := sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6)))
vestingStartTime := time.Now().Add(-30 * 24 * time.Hour) // 30 days in past
periods := vesting.Periods{
vesting.Period{
Length: 45 * 24 * 60 * 60, // 45 days
Amount: balance,
},
}
vacc := createVestingAccount(balance, vestingStartTime, periods)
newVestingStartTime := vestingStartTime.Add(30 * 24 * time.Hour)
spendableBefore := vacc.SpendableCoins(newVestingStartTime)
ResetPeriodicVestingAccount(vacc, newVestingStartTime)
// new period length 15 days
expectedEndtime := newVestingStartTime.Add(15 * 24 * time.Hour).Unix()
// new period length changed, amount unchanged
expectedPeriods := vesting.Periods{
vesting.Period{
Length: 15 * 24 * 60 * 60, // 15 days
Amount: balance,
},
}
assert.Equal(t, balance, vacc.OriginalVesting, "expected original vesting to be unchanged")
assert.Equal(t, newVestingStartTime.Unix(), vacc.StartTime, "expected vesting start time to be updated")
assert.Equal(t, expectedEndtime, vacc.EndTime, "expected vesting end time end at last period")
assert.Equal(t, expectedPeriods, vacc.VestingPeriods, "expected vesting periods to be updated")
assert.Equal(t, spendableBefore, vacc.SpendableCoins(newVestingStartTime), "expected spendable coins to be unchanged")
}
func TestResetPeriodVestingAccount_SingleVestingPeriod_ExactStartTime(t *testing.T) {
balance := sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6)))
vestingStartTime := time.Now().Add(-30 * 24 * time.Hour) // 30 days in past
periods := vesting.Periods{
vesting.Period{
Length: 30 * 24 * 60 * 60, // 30 days - exact on the start time
Amount: balance,
},
}
vacc := createVestingAccount(balance, vestingStartTime, periods)
newVestingStartTime := vestingStartTime.Add(30 * 24 * time.Hour)
spendableBefore := vacc.SpendableCoins(newVestingStartTime)
ResetPeriodicVestingAccount(vacc, newVestingStartTime)
// new period length is 0
expectedEndtime := newVestingStartTime.Unix()
// new period length changed, amount unchanged
expectedPeriods := vesting.Periods{}
assert.Equal(t, sdk.Coins{}, vacc.OriginalVesting, "expected original vesting to be unchanged")
assert.Equal(t, newVestingStartTime.Unix(), vacc.StartTime, "expected vesting start time to be updated")
assert.Equal(t, expectedEndtime, vacc.EndTime, "expected vesting end time end at last period")
assert.Equal(t, expectedPeriods, vacc.VestingPeriods, "expected vesting periods to be updated")
assert.Equal(t, spendableBefore, vacc.SpendableCoins(newVestingStartTime), "expected spendable coins to be unchanged")
}
func TestResetPeriodVestingAccount_MultiplePeriods(t *testing.T) {
balance := sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(3e6)))
vestingStartTime := time.Now().Add(-30 * 24 * time.Hour) // 30 days in past
periods := vesting.Periods{
vesting.Period{
Length: 15 * 24 * 60 * 60, // -15 days - vested
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))),
},
vesting.Period{
Length: 30 * 24 * 60 * 60, // 0 days - exact on the start time
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))),
},
vesting.Period{
Length: 45 * 24 * 60 * 60, // +15 days - vesting
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))),
},
}
vacc := createVestingAccount(balance, vestingStartTime, periods)
newVestingStartTime := vestingStartTime.Add(30 * 24 * time.Hour)
spendableBefore := vacc.SpendableCoins(newVestingStartTime)
ResetPeriodicVestingAccount(vacc, newVestingStartTime)
// new period length 15 days
expectedEndtime := newVestingStartTime.Add(15 * 24 * time.Hour).Unix()
// new period length changed, amount unchanged
expectedPeriods := vesting.Periods{
vesting.Period{
Length: 0, // 0 days
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))),
},
vesting.Period{
Length: 15 * 24 * 60 * 60, // 15 days
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))),
},
}
assert.Equal(t, sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(2e6))), vacc.OriginalVesting, "expected original vesting to be updated")
assert.Equal(t, newVestingStartTime.Unix(), vacc.StartTime, "expected vesting start time to be updated")
assert.Equal(t, expectedEndtime, vacc.EndTime, "expected vesting end time end at last period")
assert.Equal(t, expectedPeriods, vacc.VestingPeriods, "expected vesting periods to be updated")
assert.Equal(t, spendableBefore, vacc.SpendableCoins(newVestingStartTime), "expected spendable coins to be unchanged")
}
func TestResetPeriodVestingAccount_DelegatedVesting_GreaterThanVesting(t *testing.T) {
balance := sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(3e6)))
vestingStartTime := time.Now().Add(-30 * 24 * time.Hour) // 30 days in past
periods := vesting.Periods{
vesting.Period{
Length: 15 * 24 * 60 * 60, // -15 days - vested
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))),
},
vesting.Period{
Length: 30 * 24 * 60 * 60, // 0 days - exact on the start time
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))),
},
vesting.Period{
Length: 45 * 24 * 60 * 60, // +15 days - vesting
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))),
},
}
vacc := createVestingAccount(balance, vestingStartTime, periods)
vacc.TrackDelegation(vestingStartTime, balance)
newVestingStartTime := vestingStartTime.Add(30 * 24 * time.Hour)
ResetPeriodicVestingAccount(vacc, newVestingStartTime)
assert.Equal(t, sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))), vacc.DelegatedFree, "expected delegated free to be updated")
assert.Equal(t, sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(2e6))), vacc.DelegatedVesting, "expected delegated vesting to be updated")
}
func TestResetPeriodVestingAccount_DelegatedVesting_LessThanVested(t *testing.T) {
balance := sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(3e6)))
vestingStartTime := time.Now().Add(-30 * 24 * time.Hour) // 30 days in past
periods := vesting.Periods{
vesting.Period{
Length: 15 * 24 * 60 * 60, // -15 days - vested
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))),
},
vesting.Period{
Length: 30 * 24 * 60 * 60, // 0 days - exact on the start time
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))),
},
vesting.Period{
Length: 45 * 24 * 60 * 60, // +15 days - vesting
Amount: sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))),
},
}
vacc := createVestingAccount(balance, vestingStartTime, periods)
vacc.TrackDelegation(vestingStartTime, sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))))
newVestingStartTime := vestingStartTime.Add(30 * 24 * time.Hour)
ResetPeriodicVestingAccount(vacc, newVestingStartTime)
assert.Equal(t, sdk.Coins(nil), vacc.DelegatedFree, "expected delegrated free to be unmodified")
assert.Equal(t, sdk.NewCoins(sdk.NewCoin("ukava", sdk.NewInt(1e6))), vacc.DelegatedVesting, "expected delegated vesting to be unmodified")
}

View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
if [ -z "$1" ]
then
echo "Usage: ./generate-test-auth-data.sh genesis.json"
exit 1
fi
jq < "$1" -c '.app_state.auth | { params: .params, accounts: [.accounts[] | select((.value.coins | length) > 0)] }' > testdata/kava-7-test-auth-state.json

View File

@ -5,7 +5,11 @@ import (
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
authexported "github.com/cosmos/cosmos-sdk/x/auth/exported"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/supply"
cryptoAmino "github.com/tendermint/tendermint/crypto/encoding/amino"
tmtypes "github.com/tendermint/tendermint/types"
@ -15,11 +19,12 @@ import (
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
v0_15swap "github.com/kava-labs/kava/x/swap/types"
v0_14validator_vesting "github.com/kava-labs/kava/x/validator-vesting"
)
var (
// TODO: update GenesisTime and chain-id for kava-8 launch
GenesisTime = time.Date(2021, 4, 8, 15, 0, 0, 0, time.UTC)
GenesisTime = time.Date(2021, 8, 30, 15, 0, 0, 0, time.UTC)
ChainID = "kava-8"
// TODO: update SWP reward per second amount before production
// TODO: add swap tokens to kavadist module account
@ -59,6 +64,14 @@ func MigrateAppState(v0_14AppState genutil.AppMap) {
v0_14Codec := makeV014Codec()
v0_15Codec := app.MakeCodec()
// Migrate auth app state
if v0_14AppState[auth.ModuleName] != nil {
var authGenState auth.GenesisState
v0_14Codec.MustUnmarshalJSON(v0_14AppState[auth.ModuleName], &authGenState)
delete(v0_14AppState, auth.ModuleName)
v0_14AppState[auth.ModuleName] = v0_15Codec.MustMarshalJSON(Auth(authGenState, GenesisTime))
}
// Migrate incentive app state
if v0_14AppState[v0_14incentive.ModuleName] != nil {
var incentiveGenState v0_14incentive.GenesisState
@ -83,11 +96,28 @@ func MigrateAppState(v0_14AppState genutil.AppMap) {
func makeV014Codec() *codec.Codec {
cdc := codec.New()
sdk.RegisterCodec(cdc)
cryptoAmino.RegisterAmino(cdc)
auth.RegisterCodec(cdc)
supply.RegisterCodec(cdc)
vesting.RegisterCodec(cdc)
v0_14validator_vesting.RegisterCodec(cdc)
v0_14committee.RegisterCodec(cdc)
v0_14incentive.RegisterCodec(cdc)
return cdc
}
// Auth migrates the auth genesis state to a new state with pruned vesting periods
func Auth(genesisState auth.GenesisState, genesisTime time.Time) auth.GenesisState {
accounts := make([]authexported.GenesisAccount, len(genesisState.Accounts))
migratedGenesisState := auth.NewGenesisState(genesisState.Params, accounts)
for i, acc := range genesisState.Accounts {
accounts[i] = authexported.GenesisAccount(MigrateAccount(acc, genesisTime))
}
return migratedGenesisState
}
// Committee migrates from a v0.14 committee genesis state to a v0.15 committee genesis state
func Committee(genesisState v0_14committee.GenesisState) v0_15committee.GenesisState {

View File

@ -5,11 +5,15 @@ import (
"os"
"path/filepath"
"testing"
"time"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/auth"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/kava-labs/kava/app"
@ -99,3 +103,94 @@ func TestIncentive(t *testing.T) {
require.JSONEq(t, string(bz), string(appState[v0_15incentive.ModuleName]))
}
// Compare migration against auto-generated snapshot to catch regressions
func TestAuth_Snapshot(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-7-test-auth-state.json"))
require.NoError(t, err)
appState := genutil.AppMap{auth.ModuleName: bz}
MigrateAppState(appState)
if _, err := os.Stat(filepath.Join("testdata", "kava-8-test-auth-state.json")); os.IsNotExist(err) {
err := ioutil.WriteFile(filepath.Join("testdata", "kava-8-test-auth-state.json"), appState[auth.ModuleName], 0644)
require.NoError(t, err)
}
snapshot, err := ioutil.ReadFile(filepath.Join("testdata", "kava-8-test-auth-state.json"))
require.NoError(t, err)
assert.JSONEq(t, string(snapshot), string(appState[auth.ModuleName]), "expected auth state snapshot to be equal")
}
func TestAuth_ParametersEqual(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-7-test-auth-state.json"))
require.NoError(t, err)
var genesisState auth.GenesisState
cdc := app.MakeCodec()
cdc.MustUnmarshalJSON(bz, &genesisState)
migratedGenesisState := Auth(genesisState, GenesisTime)
assert.Equal(t, genesisState.Params, migratedGenesisState.Params, "expected auth parameters to not change")
}
func TestAuth_AccountConversion(t *testing.T) {
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-7-test-auth-state.json"))
require.NoError(t, err)
var genesisState auth.GenesisState
cdc := app.MakeCodec()
cdc.MustUnmarshalJSON(bz, &genesisState)
migratedGenesisState := Auth(genesisState, GenesisTime)
require.Equal(t, len(genesisState.Accounts), len(migratedGenesisState.Accounts), "expected the number of accounts after migration to be equal")
err = auth.ValidateGenesis(migratedGenesisState)
require.NoError(t, err, "expected migrated genesis to be valid")
for i, acc := range migratedGenesisState.Accounts {
oldAcc := genesisState.Accounts[i]
// total owned coins does not change
require.Equal(t, oldAcc.GetCoins(), acc.GetCoins(), "expected base coins to not change")
// ensure spenable coins at genesis time is equal
require.Equal(t, oldAcc.SpendableCoins(GenesisTime), acc.SpendableCoins(GenesisTime), "expected spendable coins to not change")
// check 30 days
futureDate := GenesisTime.Add(30 * 24 * time.Hour)
require.Equal(t, oldAcc.SpendableCoins(futureDate), acc.SpendableCoins(futureDate), "expected spendable coins to not change")
// check 90 days
futureDate = GenesisTime.Add(90 * 24 * time.Hour)
require.Equal(t, oldAcc.SpendableCoins(futureDate), acc.SpendableCoins(futureDate), "expected spendable coins to not change")
// check 180 days
futureDate = GenesisTime.Add(180 * 24 * time.Hour)
require.Equal(t, oldAcc.SpendableCoins(futureDate), acc.SpendableCoins(futureDate), "expected spendable coins to not change")
// check 365 days
futureDate = GenesisTime.Add(365 * 24 * time.Hour)
require.Equal(t, oldAcc.SpendableCoins(futureDate), acc.SpendableCoins(futureDate), "expected spendable coins to not change")
if vacc, ok := acc.(*vesting.PeriodicVestingAccount); ok {
// old account must be a periodic vesting account
oldVacc, ok := oldAcc.(*vesting.PeriodicVestingAccount)
require.True(t, ok)
// total delegated coins must match
oldTotalDelegated := oldVacc.DelegatedFree.Add(oldVacc.DelegatedVesting...)
newTotalDelegated := vacc.DelegatedFree.Add(vacc.DelegatedVesting...)
require.Equal(t, oldTotalDelegated, newTotalDelegated, "expected total amount of tracked delegations to not change")
// delegated vesting must be less or equal to original vesting
require.True(t, vacc.DelegatedVesting.IsAllLTE(vacc.OriginalVesting), "expected delegated vesting to be less or equal to original vesting")
// vested coins must be nil for the new account
require.Equal(t, sdk.Coins(nil), vacc.GetVestedCoins(GenesisTime), "expected no vested coins at genesis time")
// vesting coins must not be nil
require.NotEqual(t, sdk.Coins(nil), vacc.GetVestingCoins(GenesisTime), "expected vesting coins to be greater than 0")
// new account as less than or equal
require.LessOrEqual(t, len(vacc.VestingPeriods), len(oldVacc.VestingPeriods), "expected vesting periods of new account to be less than or equal to old")
}
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long