0g-chain/x/validator-vesting/abci_test.go

373 lines
11 KiB
Go
Raw Normal View History

2019-09-27 18:48:57 +00:00
package validatorvesting
import (
"testing"
"time"
"github.com/stretchr/testify/require"
2020-04-30 14:23:41 +00:00
sdk "github.com/cosmos/cosmos-sdk/types"
2019-09-27 18:48:57 +00:00
abci "github.com/tendermint/tendermint/abci/types"
tmtime "github.com/tendermint/tendermint/types/time"
"github.com/cosmos/cosmos-sdk/x/staking"
stakingexported "github.com/cosmos/cosmos-sdk/x/staking/exported"
2020-04-30 14:13:31 +00:00
"github.com/kava-labs/kava/x/validator-vesting/keeper"
"github.com/kava-labs/kava/x/validator-vesting/types"
2019-09-27 18:48:57 +00:00
)
2019-10-09 22:42:23 +00:00
func TestBeginBlockerZeroHeight(t *testing.T) {
ctx, ak, _, stakingKeeper, _, vvk := keeper.CreateTestInput(t, false, 1000)
now := tmtime.Now()
vva := keeper.ValidatorVestingDelegatorTestAccount(now)
ak.SetAccount(ctx, vva)
delTokens := sdk.TokensFromConsensusPower(30)
vvk.SetValidatorVestingAccountKey(ctx, vva.Address)
keeper.CreateValidators(ctx, stakingKeeper, []int64{5, 5, 5})
val1, found := stakingKeeper.GetValidator(ctx, keeper.ValOpAddr1)
require.True(t, found)
_, err := stakingKeeper.Delegate(ctx, vva.Address, delTokens, sdk.Unbonded, val1, true)
require.NoError(t, err)
_ = staking.EndBlocker(ctx, stakingKeeper)
// require that there exists one delegation
var delegations int
stakingKeeper.IterateDelegations(ctx, vva.Address, func(index int64, d stakingexported.DelegationI) (stop bool) {
delegations++
return false
})
require.Equal(t, 1, delegations)
val := abci.Validator{
Address: val1.ConsPubKey.Address(),
Power: val1.ConsensusPower(),
}
vva.ValidatorAddress = val1.ConsAddress()
ak.SetAccount(ctx, vva)
height := int64(1)
blockTime := now
addHour := func(t time.Time) time.Time { return t.Add(1 * time.Hour) }
header := abci.Header{Height: height, Time: addHour(blockTime)}
ctx = ctx.WithBlockHeader(header)
// mark the validator as absent
req := abci.RequestBeginBlock{
Header: header,
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{{
Validator: abci.Validator{},
SignedLastBlock: false,
}},
},
}
BeginBlocker(ctx, req, vvk)
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
// require missed block counter doesn't increment because there's no voting history
require.Equal(t, types.CurrentPeriodProgress{MissedBlocks: 0, TotalBlocks: 1}, vva.CurrentPeriodProgress)
2019-10-09 22:42:23 +00:00
// mark the validator as having missed
req = abci.RequestBeginBlock{
Header: header,
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{{
Validator: val,
SignedLastBlock: false,
}},
},
}
BeginBlocker(ctx, req, vvk)
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
require.Equal(t, types.CurrentPeriodProgress{MissedBlocks: 0, TotalBlocks: 2}, vva.CurrentPeriodProgress)
2019-10-09 22:42:23 +00:00
}
2019-09-27 18:48:57 +00:00
func TestBeginBlockerSignedBlock(t *testing.T) {
ctx, ak, _, stakingKeeper, _, vvk := keeper.CreateTestInput(t, false, 1000)
now := tmtime.Now()
vva := keeper.ValidatorVestingDelegatorTestAccount(now)
ak.SetAccount(ctx, vva)
delTokens := sdk.TokensFromConsensusPower(30)
vvk.SetValidatorVestingAccountKey(ctx, vva.Address)
keeper.CreateValidators(ctx, stakingKeeper, []int64{5, 5, 5})
val1, found := stakingKeeper.GetValidator(ctx, keeper.ValOpAddr1)
require.True(t, found)
_, err := stakingKeeper.Delegate(ctx, vva.Address, delTokens, sdk.Unbonded, val1, true)
require.NoError(t, err)
_ = staking.EndBlocker(ctx, stakingKeeper)
// require that there exists one delegation
var delegations int
stakingKeeper.IterateDelegations(ctx, vva.Address, func(index int64, d stakingexported.DelegationI) (stop bool) {
delegations++
return false
})
require.Equal(t, 1, delegations)
val := abci.Validator{
Address: val1.ConsPubKey.Address(),
Power: val1.ConsensusPower(),
}
vva.ValidatorAddress = val1.ConsAddress()
ak.SetAccount(ctx, vva)
2019-10-09 22:42:23 +00:00
height := int64(1)
2019-09-27 18:48:57 +00:00
blockTime := now
addHour := func(t time.Time) time.Time { return t.Add(1 * time.Hour) }
header := abci.Header{Height: height, Time: addHour(blockTime)}
2019-10-09 22:42:23 +00:00
ctx = ctx.WithBlockHeader(header)
2019-09-27 18:48:57 +00:00
// mark the validator as having signed
req := abci.RequestBeginBlock{
Header: header,
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{{
Validator: val,
SignedLastBlock: true,
}},
},
}
BeginBlocker(ctx, req, vvk)
height++
blockTime = addHour(blockTime)
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
2019-10-04 17:55:49 +00:00
require.Equal(t, types.CurrentPeriodProgress{0, 1}, vva.CurrentPeriodProgress)
2019-09-27 18:48:57 +00:00
header = abci.Header{Height: height, Time: addHour(blockTime)}
2019-10-09 22:42:23 +00:00
// mark the validator as having signed
ctx = ctx.WithBlockHeader(header)
req = abci.RequestBeginBlock{
Header: header,
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{{
Validator: val,
SignedLastBlock: true,
}},
},
}
2019-09-27 18:48:57 +00:00
2019-10-09 22:42:23 +00:00
BeginBlocker(ctx, req, vvk)
height++
blockTime = addHour(blockTime)
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
require.Equal(t, types.CurrentPeriodProgress{0, 2}, vva.CurrentPeriodProgress)
header = abci.Header{Height: height, Time: addHour(blockTime)}
ctx = ctx.WithBlockHeader(header)
2019-09-27 18:48:57 +00:00
// mark the validator as having missed
req = abci.RequestBeginBlock{
Header: header,
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{{
Validator: val,
SignedLastBlock: false,
}},
},
}
BeginBlocker(ctx, req, vvk)
height++
blockTime = addHour(blockTime)
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
2019-10-09 22:42:23 +00:00
require.Equal(t, types.CurrentPeriodProgress{1, 3}, vva.CurrentPeriodProgress)
2019-09-27 18:48:57 +00:00
2019-10-09 22:42:23 +00:00
header = abci.Header{Height: height, Time: addHour(blockTime)}
ctx = ctx.WithBlockHeader(header)
2019-09-27 18:48:57 +00:00
// mark the validator as being absent
req = abci.RequestBeginBlock{
Header: header,
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{{
Validator: abci.Validator{},
SignedLastBlock: true,
}},
},
}
BeginBlocker(ctx, req, vvk)
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
2019-10-09 22:42:23 +00:00
require.Equal(t, types.CurrentPeriodProgress{2, 4}, vva.CurrentPeriodProgress)
2019-09-27 18:48:57 +00:00
}
func TestBeginBlockerSuccessfulPeriod(t *testing.T) {
2019-10-09 22:42:23 +00:00
height := int64(1)
2019-09-27 18:48:57 +00:00
now := tmtime.Now()
blockTime := now
numBlocks := int64(14)
addHour := func(t time.Time) time.Time { return t.Add(1 * time.Hour) }
ctx, ak, _, stakingKeeper, _, vvk := keeper.CreateTestInput(t, false, 1000)
vva := keeper.ValidatorVestingDelegatorTestAccount(now)
ak.SetAccount(ctx, vva)
vvk.SetValidatorVestingAccountKey(ctx, vva.Address)
keeper.CreateValidators(ctx, stakingKeeper, []int64{5, 5, 5})
val1, found := stakingKeeper.GetValidator(ctx, keeper.ValOpAddr1)
require.True(t, found)
_ = staking.EndBlocker(ctx, stakingKeeper)
val := abci.Validator{
Address: val1.ConsPubKey.Address(),
Power: val1.ConsensusPower(),
}
vva.ValidatorAddress = val1.ConsAddress()
ak.SetAccount(ctx, vva)
for ; height < numBlocks; height++ {
header := abci.Header{Height: height, Time: addHour(blockTime)}
// mark the validator as having signed
req := abci.RequestBeginBlock{
Header: header,
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{{
Validator: val,
SignedLastBlock: true,
}},
},
}
ctx = ctx.WithBlockHeader(header)
BeginBlocker(ctx, req, vvk)
blockTime = addHour(blockTime)
2019-10-09 22:42:23 +00:00
if height == 12 {
2019-09-27 18:48:57 +00:00
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
// require that missing sign count is set back to zero after the period increments.
2019-10-04 17:55:49 +00:00
require.Equal(t, types.CurrentPeriodProgress{0, 0}, vva.CurrentPeriodProgress)
2019-09-27 18:48:57 +00:00
}
}
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
// t.Log(vva.MarshalYAML())
2020-04-30 14:13:31 +00:00
require.Equal(t, []types.VestingProgress{{true, true}, {false, false}, {false, false}}, vva.VestingPeriodProgress)
2019-09-27 18:48:57 +00:00
}
func TestBeginBlockerUnsuccessfulPeriod(t *testing.T) {
2019-10-09 22:42:23 +00:00
height := int64(1)
2019-09-27 18:48:57 +00:00
now := tmtime.Now()
blockTime := now
2019-10-09 22:42:23 +00:00
numBlocks := int64(13)
2019-09-27 18:48:57 +00:00
addHour := func(t time.Time) time.Time { return t.Add(1 * time.Hour) }
2019-10-04 17:55:49 +00:00
ctx, ak, _, stakingKeeper, supplyKeeper, vvk := keeper.CreateTestInput(t, false, 1000)
initialSupply := supplyKeeper.GetSupply(ctx).GetTotal()
2019-09-27 18:48:57 +00:00
keeper.CreateValidators(ctx, stakingKeeper, []int64{5, 5, 5})
vva := keeper.ValidatorVestingDelegatorTestAccount(now)
ak.SetAccount(ctx, vva)
2019-10-04 17:55:49 +00:00
// delegate all coins
2019-09-27 18:48:57 +00:00
delTokens := sdk.TokensFromConsensusPower(60)
vvk.SetValidatorVestingAccountKey(ctx, vva.Address)
val1, found := stakingKeeper.GetValidator(ctx, keeper.ValOpAddr1)
require.True(t, found)
_, err := stakingKeeper.Delegate(ctx, vva.Address, delTokens, sdk.Unbonded, val1, true)
require.NoError(t, err)
_ = staking.EndBlocker(ctx, stakingKeeper)
// note that delegation modifies the account's state!
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
val := abci.Validator{
Address: val1.ConsPubKey.Address(),
Power: val1.ConsensusPower(),
}
vva.ValidatorAddress = val1.ConsAddress()
ak.SetAccount(ctx, vva)
// run one period's worth of blocks
for ; height < numBlocks; height++ {
header := abci.Header{Height: height, Time: addHour(blockTime)}
// mark the validator as having missed
req := abci.RequestBeginBlock{
Header: header,
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{{
Validator: val,
SignedLastBlock: false,
}},
},
}
ctx = ctx.WithBlockHeader(header)
BeginBlocker(ctx, req, vvk)
blockTime = addHour(blockTime)
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
}
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
2020-04-30 14:13:31 +00:00
// check that the period was unsuccessful
require.Equal(t, []types.VestingProgress{{true, false}, {false, false}, {false, false}}, vva.VestingPeriodProgress)
2019-09-27 18:48:57 +00:00
// check that there is debt after the period.
require.Equal(t, sdk.Coins{sdk.NewInt64Coin("stake", 30000000)}, vva.DebtAfterFailedVesting)
var delegations int
stakingKeeper.IterateDelegations(ctx, vva.Address, func(index int64, d stakingexported.DelegationI) (stop bool) {
delegations++
return false
})
// require that all delegations were unbonded
require.Equal(t, 0, delegations)
2019-10-04 17:55:49 +00:00
// complete the unbonding period
header := abci.Header{Height: height, Time: blockTime.Add(time.Hour * 2)}
req := abci.RequestBeginBlock{
Header: header,
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{{
Validator: val,
SignedLastBlock: false,
}},
},
}
ctx = ctx.WithBlockHeader(header)
BeginBlocker(ctx, req, vvk)
_ = staking.EndBlocker(ctx, stakingKeeper)
header = abci.Header{Height: height, Time: blockTime.Add(time.Hour * 2)}
req = abci.RequestBeginBlock{
Header: header,
LastCommitInfo: abci.LastCommitInfo{
Votes: []abci.VoteInfo{{
Validator: val,
SignedLastBlock: false,
}},
},
}
ctx = ctx.WithBlockHeader(header)
BeginBlocker(ctx, req, vvk)
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
// require that debt has reset to zero and coins balance is reduced by period 1 amount.
require.Equal(t, vva.GetCoins(), sdk.Coins{sdk.NewInt64Coin("stake", 30000000)})
require.Equal(t, sdk.Coins(nil), vva.DebtAfterFailedVesting)
// require that the supply has decreased by period 1 amount
require.Equal(t, initialSupply.Sub(vva.VestingPeriods[0].Amount), supplyKeeper.GetSupply(ctx).GetTotal())
2019-09-27 18:48:57 +00:00
}