mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 23:35:19 +00:00
rebase, handle first block
This commit is contained in:
parent
49279a3ce5
commit
3908870761
@ -94,9 +94,12 @@ func AddGenesisAccountCmd(
|
||||
|
||||
baseAccount := auth.NewBaseAccount(addr, coins.Sort(), nil, 0, 0)
|
||||
if !vestingAmt.IsZero() {
|
||||
baseVestingAccount := vesting.NewBaseVestingAccount(
|
||||
baseVestingAccount, err := vesting.NewBaseVestingAccount(
|
||||
baseAccount, vestingAmt.Sort(), vestingEnd,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to create base vesting account: %w", err)
|
||||
}
|
||||
|
||||
switch {
|
||||
case vestingPeriodsFile != "":
|
||||
|
@ -24,24 +24,31 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper)
|
||||
validatorVestingKeys := k.GetAllAccountKeys(ctx)
|
||||
for _, key := range validatorVestingKeys {
|
||||
acc := k.GetAccountFromAuthKeeper(ctx, key)
|
||||
vote, found := voteInfos.FilterByValidatorAddress(acc.ValidatorAddress)
|
||||
if !found || !vote.SignedLastBlock {
|
||||
// if the validator was not found or explicitly didn't sign, increment the missing sign count
|
||||
k.UpdateMissingSignCount(ctx, acc.GetAddress(), true)
|
||||
} else {
|
||||
k.UpdateMissingSignCount(ctx, acc.GetAddress(), false)
|
||||
}
|
||||
|
||||
// check if a period ended in the last block
|
||||
endTimes := k.GetPeriodEndTimes(ctx, key)
|
||||
|
||||
for i, t := range endTimes {
|
||||
if currentBlockTime.Unix() >= t && previousBlockTime.Unix() < t {
|
||||
k.UpdateVestedCoinsProgress(ctx, key, i)
|
||||
if k.AccountIsVesting(ctx, acc.GetAddress()) {
|
||||
vote, found := voteInfos.FilterByValidatorAddress(acc.ValidatorAddress)
|
||||
if !found || !vote.SignedLastBlock {
|
||||
if ctx.BlockHeight() <= 1 {
|
||||
// don't count missed blocks on block 1 since there is no vote history
|
||||
k.UpdateMissingSignCount(ctx, acc.GetAddress(), false)
|
||||
} else {
|
||||
// if the validator was not found or explicitly didn't sign, increment the missing sign count
|
||||
k.UpdateMissingSignCount(ctx, acc.GetAddress(), true)
|
||||
}
|
||||
} else {
|
||||
k.UpdateMissingSignCount(ctx, acc.GetAddress(), false)
|
||||
}
|
||||
|
||||
// check if a period ended in the last block
|
||||
endTimes := k.GetPeriodEndTimes(ctx, key)
|
||||
|
||||
for i, t := range endTimes {
|
||||
if currentBlockTime.Unix() >= t && previousBlockTime.Unix() < t {
|
||||
k.UpdateVestedCoinsProgress(ctx, key, i)
|
||||
}
|
||||
}
|
||||
// handle any new/remaining debt on the account
|
||||
k.HandleVestingDebt(ctx, key, currentBlockTime)
|
||||
}
|
||||
// handle any new/remaining debt on the account
|
||||
k.HandleVestingDebt(ctx, key, currentBlockTime)
|
||||
}
|
||||
k.SetPreviousBlockTime(ctx, currentBlockTime)
|
||||
}
|
||||
|
@ -15,6 +15,81 @@ import (
|
||||
"github.com/kava-labs/kava/x/validator-vesting/internal/types"
|
||||
)
|
||||
|
||||
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{0, 1}, vva.CurrentPeriodProgress)
|
||||
|
||||
// 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{0, 2}, vva.CurrentPeriodProgress)
|
||||
}
|
||||
|
||||
func TestBeginBlockerSignedBlock(t *testing.T) {
|
||||
ctx, ak, _, stakingKeeper, _, vvk := keeper.CreateTestInput(t, false, 1000)
|
||||
now := tmtime.Now()
|
||||
@ -51,13 +126,13 @@ func TestBeginBlockerSignedBlock(t *testing.T) {
|
||||
vva.ValidatorAddress = val1.ConsAddress()
|
||||
ak.SetAccount(ctx, vva)
|
||||
|
||||
height := int64(0)
|
||||
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 having signed
|
||||
req := abci.RequestBeginBlock{
|
||||
Header: header,
|
||||
@ -76,7 +151,26 @@ func TestBeginBlockerSignedBlock(t *testing.T) {
|
||||
require.Equal(t, types.CurrentPeriodProgress{0, 1}, vva.CurrentPeriodProgress)
|
||||
|
||||
header = abci.Header{Height: height, Time: addHour(blockTime)}
|
||||
// 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,
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
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)
|
||||
// mark the validator as having missed
|
||||
req = abci.RequestBeginBlock{
|
||||
Header: header,
|
||||
@ -92,8 +186,10 @@ func TestBeginBlockerSignedBlock(t *testing.T) {
|
||||
height++
|
||||
blockTime = addHour(blockTime)
|
||||
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
|
||||
require.Equal(t, types.CurrentPeriodProgress{1, 2}, vva.CurrentPeriodProgress)
|
||||
require.Equal(t, types.CurrentPeriodProgress{1, 3}, vva.CurrentPeriodProgress)
|
||||
|
||||
header = abci.Header{Height: height, Time: addHour(blockTime)}
|
||||
ctx = ctx.WithBlockHeader(header)
|
||||
// mark the validator as being absent
|
||||
req = abci.RequestBeginBlock{
|
||||
Header: header,
|
||||
@ -106,14 +202,12 @@ func TestBeginBlockerSignedBlock(t *testing.T) {
|
||||
}
|
||||
|
||||
BeginBlocker(ctx, req, vvk)
|
||||
height++
|
||||
blockTime = addHour(blockTime)
|
||||
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
|
||||
require.Equal(t, types.CurrentPeriodProgress{2, 3}, vva.CurrentPeriodProgress)
|
||||
require.Equal(t, types.CurrentPeriodProgress{2, 4}, vva.CurrentPeriodProgress)
|
||||
}
|
||||
|
||||
func TestBeginBlockerSuccessfulPeriod(t *testing.T) {
|
||||
height := int64(0)
|
||||
height := int64(1)
|
||||
now := tmtime.Now()
|
||||
blockTime := now
|
||||
numBlocks := int64(14)
|
||||
@ -156,7 +250,7 @@ func TestBeginBlockerSuccessfulPeriod(t *testing.T) {
|
||||
BeginBlocker(ctx, req, vvk)
|
||||
blockTime = addHour(blockTime)
|
||||
|
||||
if height == 11 {
|
||||
if height == 12 {
|
||||
vva = vvk.GetAccountFromAuthKeeper(ctx, vva.Address)
|
||||
// require that missing sign count is set back to zero after the period increments.
|
||||
require.Equal(t, types.CurrentPeriodProgress{0, 0}, vva.CurrentPeriodProgress)
|
||||
@ -170,10 +264,10 @@ func TestBeginBlockerSuccessfulPeriod(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBeginBlockerUnsuccessfulPeriod(t *testing.T) {
|
||||
height := int64(0)
|
||||
height := int64(1)
|
||||
now := tmtime.Now()
|
||||
blockTime := now
|
||||
numBlocks := int64(12)
|
||||
numBlocks := int64(13)
|
||||
addHour := func(t time.Time) time.Time { return t.Add(1 * time.Hour) }
|
||||
|
||||
ctx, ak, _, stakingKeeper, supplyKeeper, vvk := keeper.CreateTestInput(t, false, 1000)
|
||||
|
@ -1,7 +1,10 @@
|
||||
// nolint
|
||||
// autogenerated code using github.com/rigelrozanski/multitool
|
||||
// aliases generated for the following subdirectories:
|
||||
// ALIASGEN: github.com/kava-labs/kava/x/validator-vesting/internal/types/
|
||||
// ALIASGEN: github.com/kava-labs/kava/x/validator-vesting/internal/keeper/
|
||||
package validatorvesting
|
||||
|
||||
// nolint
|
||||
// DONTCOVER
|
||||
import (
|
||||
"github.com/kava-labs/kava/x/validator-vesting/internal/keeper"
|
||||
"github.com/kava-labs/kava/x/validator-vesting/internal/types"
|
||||
@ -13,19 +16,49 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
NewValidatorVestingAccountRaw = types.NewValidatorVestingAccountRaw
|
||||
NewValidatorVestingAccount = types.NewValidatorVestingAccount
|
||||
NewGenesisState = types.NewGenesisState
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
RegisterCodec = types.RegisterCodec
|
||||
ValidatorVestingAccountPrefix = types.ValidatorVestingAccountPrefix
|
||||
// functions aliases
|
||||
RegisterCodec = types.RegisterCodec
|
||||
NewGenesisState = types.NewGenesisState
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
ValidateGenesis = types.ValidateGenesis
|
||||
ValidatorVestingAccountKey = types.ValidatorVestingAccountKey
|
||||
CreateTestAddrs = types.CreateTestAddrs
|
||||
TestAddr = types.TestAddr
|
||||
CreateTestPubKeys = types.CreateTestPubKeys
|
||||
NewPubKey = types.NewPubKey
|
||||
NewValidatorVestingAccountRaw = types.NewValidatorVestingAccountRaw
|
||||
NewValidatorVestingAccount = types.NewValidatorVestingAccount
|
||||
NewKeeper = keeper.NewKeeper
|
||||
MakeTestCodec = keeper.MakeTestCodec
|
||||
CreateTestInput = keeper.CreateTestInput
|
||||
ValidatorVestingTestAccount = keeper.ValidatorVestingTestAccount
|
||||
ValidatorVestingTestAccounts = keeper.ValidatorVestingTestAccounts
|
||||
ValidatorVestingDelegatorTestAccount = keeper.ValidatorVestingDelegatorTestAccount
|
||||
CreateValidators = keeper.CreateValidators
|
||||
|
||||
// variable aliases
|
||||
ModuleCdc = types.ModuleCdc
|
||||
BlocktimeKey = types.BlocktimeKey
|
||||
ValidatorVestingAccountKey = types.ValidatorVestingAccountKey
|
||||
NewKeeper = keeper.NewKeeper
|
||||
ValidatorVestingAccountPrefix = types.ValidatorVestingAccountPrefix
|
||||
ValOpPk1 = keeper.ValOpPk1
|
||||
ValOpPk2 = keeper.ValOpPk2
|
||||
ValOpPk3 = keeper.ValOpPk3
|
||||
ValOpAddr1 = keeper.ValOpAddr1
|
||||
ValOpAddr2 = keeper.ValOpAddr2
|
||||
ValOpAddr3 = keeper.ValOpAddr3
|
||||
ValConsPk11 = keeper.ValConsPk11
|
||||
ValConsPk12 = keeper.ValConsPk12
|
||||
ValConsPk13 = keeper.ValConsPk13
|
||||
ValConsAddr1 = keeper.ValConsAddr1
|
||||
ValConsAddr2 = keeper.ValConsAddr2
|
||||
ValConsAddr3 = keeper.ValConsAddr3
|
||||
TestAddrs = keeper.TestAddrs
|
||||
)
|
||||
|
||||
type (
|
||||
GenesisState = types.GenesisState
|
||||
Keeper = keeper.Keeper
|
||||
VestingProgress = types.VestingProgress
|
||||
CurrentPeriodProgress = types.CurrentPeriodProgress
|
||||
ValidatorVestingAccount = types.ValidatorVestingAccount
|
||||
Keeper = keeper.Keeper
|
||||
)
|
||||
|
@ -135,12 +135,14 @@ func (k Keeper) SetVestingProgress(ctx sdk.Context, addr sdk.AccAddress, period
|
||||
k.ak.SetAccount(ctx, vv)
|
||||
}
|
||||
|
||||
// AddDebt adds the input amount to DebtAfterFailedVesting field
|
||||
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)
|
||||
}
|
||||
|
||||
// ResetCurrentPeriodProgress resets CurrentPeriodProgress to zero values
|
||||
func (k Keeper) ResetCurrentPeriodProgress(ctx sdk.Context, addr sdk.AccAddress) {
|
||||
vv := k.GetAccountFromAuthKeeper(ctx, addr)
|
||||
vv.CurrentPeriodProgress = types.CurrentPeriodProgress{TotalBlocks: 0, MissedBlocks: 0}
|
||||
@ -202,3 +204,17 @@ func (k Keeper) GetPeriodEndTimes(ctx sdk.Context, addr sdk.AccAddress) []int64
|
||||
}
|
||||
return endTimes
|
||||
}
|
||||
|
||||
// AccountIsVesting returns true if all vesting periods is complete and there is no debt
|
||||
func (k Keeper) AccountIsVesting(ctx sdk.Context, addr sdk.AccAddress) bool {
|
||||
vv := k.GetAccountFromAuthKeeper(ctx, addr)
|
||||
if !vv.DebtAfterFailedVesting.IsZero() {
|
||||
return false
|
||||
}
|
||||
for _, p := range vv.VestingPeriodProgress {
|
||||
if !p.PeriodComplete {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -102,6 +102,25 @@ func TestGetEndTImes(t *testing.T) {
|
||||
require.Equal(t, expectedEndTimes, endTimes)
|
||||
}
|
||||
|
||||
func TestAccountIsVesting(t *testing.T) {
|
||||
ctx, ak, _, _, _, keeper := CreateTestInput(t, false, 1000)
|
||||
|
||||
now := tmtime.Now()
|
||||
|
||||
vva := ValidatorVestingDelegatorTestAccount(now)
|
||||
ak.SetAccount(ctx, vva)
|
||||
keeper.SetValidatorVestingAccountKey(ctx, vva.Address)
|
||||
|
||||
require.Equal(t, false, keeper.AccountIsVesting(ctx, vva.Address))
|
||||
|
||||
for i := range vva.VestingPeriodProgress {
|
||||
vva.VestingPeriodProgress[i] = types.VestingProgress{true, true}
|
||||
ak.SetAccount(ctx, vva)
|
||||
}
|
||||
require.Equal(t, true, keeper.AccountIsVesting(ctx, vva.Address))
|
||||
|
||||
}
|
||||
|
||||
func TestSetMissingSignCount(t *testing.T) {
|
||||
ctx, ak, _, _, _, keeper := CreateTestInput(t, false, 1000)
|
||||
|
||||
@ -142,7 +161,7 @@ func TestUpdateVestedCoinsProgress(t *testing.T) {
|
||||
vva = keeper.GetAccountFromAuthKeeper(ctx, vva.Address)
|
||||
keeper.UpdateVestedCoinsProgress(ctx, vva.Address, 0)
|
||||
vva = keeper.GetAccountFromAuthKeeper(ctx, vva.Address)
|
||||
// require that debt is zero
|
||||
// require that debt is zerox
|
||||
require.Equal(t, sdk.Coins(nil), vva.DebtAfterFailedVesting)
|
||||
// require that the first vesting progress variable is successful
|
||||
require.Equal(t, []types.VestingProgress{types.VestingProgress{true, true}, types.VestingProgress{false, false}, types.VestingProgress{false, false}}, vva.VestingPeriodProgress)
|
||||
|
@ -32,7 +32,7 @@ type VestingProgress struct {
|
||||
// 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`
|
||||
TotalBlocks int64 `json:"total_blocks" yaml:"total_blocks"`
|
||||
}
|
||||
|
||||
// GetSignedPercentage returns the percentage of blocks signed for the current vesting period
|
||||
@ -63,7 +63,7 @@ type ValidatorVestingAccount struct {
|
||||
ValidatorAddress sdk.ConsAddress `json:"validator_address" yaml:"validator_address"`
|
||||
ReturnAddress sdk.AccAddress `json:"return_address" yaml:"return_address"`
|
||||
SigningThreshold int64 `json:"signing_threshold" yaml:"signing_threshold"`
|
||||
CurrentPeriodProgress CurrentPeriodProgress `json:"missing_sign_count" yaml:"missing_sign_count"`
|
||||
CurrentPeriodProgress CurrentPeriodProgress `json:"current_period_progress" yaml:"current_period_progress"`
|
||||
VestingPeriodProgress []VestingProgress `json:"vesting_period_progress" yaml:"vesting_period_progress"`
|
||||
DebtAfterFailedVesting sdk.Coins `json:"debt_after_failed_vesting" yaml:"debt_after_failed_vesting"`
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ func TestNewAccount(t *testing.T) {
|
||||
origCoins := sdk.Coins{sdk.NewInt64Coin(feeDenom, 1000), sdk.NewInt64Coin(stakeDenom, 100)}
|
||||
bacc := auth.NewBaseAccountWithAddress(testAddr)
|
||||
bacc.SetCoins(origCoins)
|
||||
bva := vesting.NewBaseVestingAccount(&bacc, origCoins, endTime)
|
||||
bva, _ := vesting.NewBaseVestingAccount(&bacc, origCoins, endTime)
|
||||
require.NotPanics(t, func() { NewValidatorVestingAccountRaw(bva, now.Unix(), periods, testConsAddr, nil, 90) })
|
||||
vva := NewValidatorVestingAccountRaw(bva, now.Unix(), periods, testConsAddr, nil, 90)
|
||||
vva.PubKey = testPk
|
||||
|
@ -3,7 +3,6 @@ package validatorvesting
|
||||
import (
|
||||
"encoding/json"
|
||||
"math/rand"
|
||||
"os"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/cobra"
|
||||
@ -40,7 +39,6 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) {
|
||||
// DefaultGenesis returns default genesis state as raw bytes for the validator-vesting
|
||||
// module.
|
||||
func (AppModuleBasic) DefaultGenesis() json.RawMessage {
|
||||
types.ModuleCdc.PrintTypes(os.Stdout)
|
||||
return types.ModuleCdc.MustMarshalJSON(types.DefaultGenesisState())
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ func RandomizedGenState(simState *module.SimulationState) {
|
||||
duration := va.GetEndTime() - va.GetStartTime()
|
||||
vestingPeriods := getRandomVestingPeriods(duration, simState.Rand, va.GetCoins())
|
||||
vestingCoins := getVestingCoins(vestingPeriods)
|
||||
bva := vestingtypes.NewBaseVestingAccount(&bacc, vestingCoins, va.GetEndTime())
|
||||
bva, _ := vestingtypes.NewBaseVestingAccount(&bacc, vestingCoins, va.GetEndTime())
|
||||
var gacc authexported.GenesisAccount
|
||||
if simState.Rand.Intn(100) < 50 {
|
||||
// convert to periodic vesting account 50%
|
||||
|
Loading…
Reference in New Issue
Block a user