Merge PR #1612: prevent zero power validators at genesis

This commit is contained in:
Christopher Goes 2018-07-10 07:43:59 +02:00 committed by GitHub
commit efa003db9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 74 additions and 10 deletions

View File

@ -129,6 +129,7 @@ BUG FIXES
* \#1461 - CLI tests now no longer reset your local environment data
* \#1505 - `gaiacli stake validator` no longer panics if validator doesn't exist
* \#1565 - fix cliff validator persisting when validator set shrinks from max
* \#1287 - prevent zero power validators at genesis
* [x/stake] fix bug when unbonding/redelegating using `--shares-percent`
* \#1010 - two validators can't bond with the same pubkey anymore

View File

@ -164,7 +164,11 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
}
// load the initial stake information
stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
err = stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
if err != nil {
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
// return sdk.ErrGenesisParse("").TraceCause(err, "")
}
gov.InitGenesis(ctx, app.govKeeper, gov.DefaultGenesisState())

View File

@ -228,8 +228,7 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
var genesisState gaia.GenesisState
err := app.cdc.UnmarshalJSON(stateJSON, &genesisState)
if err != nil {
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468
// return sdk.ErrGenesisParse("").TraceCause(err, "")
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "")
}
// load the accounts
@ -239,7 +238,10 @@ func (app *GaiaApp) initChainer(ctx sdk.Context, req abci.RequestInitChain) abci
}
// load the initial stake information
stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
return abci.ResponseInitChain{}
err = stake.InitGenesis(ctx, app.stakeKeeper, genesisState.StakeData)
if err != nil {
panic(err) // TODO https://github.com/cosmos/cosmos-sdk/issues/468 // return sdk.ErrGenesisParse("").TraceCause(err, "")
}
return abci.ResponseInitChain{}
}

View File

@ -61,7 +61,10 @@ func getInitChainer(mapp *mock.App, keeper Keeper, stakeKeeper stake.Keeper) sdk
stakeGenesis := stake.DefaultGenesisState()
stakeGenesis.Pool.LooseTokens = 100000
stake.InitGenesis(ctx, stakeKeeper, stakeGenesis)
err := stake.InitGenesis(ctx, stakeKeeper, stakeGenesis)
if err != nil {
panic(err)
}
InitGenesis(ctx, keeper, DefaultGenesisState())
return abci.ResponseInitChain{}
}

View File

@ -55,7 +55,10 @@ func getInitChainer(mapp *mock.App, keeper stake.Keeper) sdk.InitChainer {
mapp.InitChainer(ctx, req)
stakeGenesis := stake.DefaultGenesisState()
stakeGenesis.Pool.LooseTokens = 100000
stake.InitGenesis(ctx, keeper, stakeGenesis)
err := stake.InitGenesis(ctx, keeper, stakeGenesis)
if err != nil {
panic(err)
}
return abci.ResponseInitChain{}
}
}

View File

@ -64,7 +64,9 @@ func createTestInput(t *testing.T) (sdk.Context, bank.Keeper, stake.Keeper, Keep
sk := stake.NewKeeper(cdc, keyStake, ck, stake.DefaultCodespace)
genesis := stake.DefaultGenesisState()
genesis.Pool.LooseTokens = initCoins.MulRaw(int64(len(addrs))).Int64()
stake.InitGenesis(ctx, sk, genesis)
err = stake.InitGenesis(ctx, sk, genesis)
require.Nil(t, err)
for _, addr := range addrs {
_, _, err = ck.AddCoins(ctx, addr, sdk.Coins{
{sk.GetParams(ctx).BondDenom, initCoins},

View File

@ -65,7 +65,10 @@ func getInitChainer(mapp *mock.App, keeper Keeper) sdk.InitChainer {
stakeGenesis := DefaultGenesisState()
stakeGenesis.Pool.LooseTokens = 100000
InitGenesis(ctx, keeper, stakeGenesis)
err := InitGenesis(ctx, keeper, stakeGenesis)
if err != nil {
panic(err)
}
return abci.ResponseInitChain{}
}

View File

@ -3,6 +3,7 @@ package stake
import (
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/stake/types"
"github.com/pkg/errors"
tmtypes "github.com/tendermint/tendermint/types"
)
@ -11,7 +12,7 @@ import (
// validator in the keeper along with manually setting the indexes. In
// addition, it also sets any delegations found in data. Finally, it updates
// the bonded validators.
func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) error {
keeper.SetPool(ctx, data.Pool)
keeper.SetNewParams(ctx, data.Params)
keeper.InitIntraTxCounter(ctx)
@ -19,6 +20,13 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
for _, validator := range data.Validators {
keeper.SetValidator(ctx, validator)
if validator.PoolShares.Amount.IsZero() {
return errors.Errorf("genesis validator cannot have zero pool shares, validator: %v", validator)
}
if validator.DelegatorShares.IsZero() {
return errors.Errorf("genesis validator cannot have zero delegator shares, validator: %v", validator)
}
// Manually set indexes for the first time
keeper.SetValidatorByPubKeyIndex(ctx, validator)
keeper.SetValidatorByPowerIndex(ctx, validator, data.Pool)
@ -33,6 +41,7 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) {
}
keeper.UpdateBondedValidatorsFull(ctx)
return nil
}
// WriteGenesis returns a GenesisState for a given context and keeper. The

37
x/stake/genesis_test.go Normal file
View File

@ -0,0 +1,37 @@
package stake
import (
"testing"
"github.com/stretchr/testify/require"
sdk "github.com/cosmos/cosmos-sdk/types"
keep "github.com/cosmos/cosmos-sdk/x/stake/keeper"
"github.com/cosmos/cosmos-sdk/x/stake/types"
)
func TestInitGenesis(t *testing.T) {
ctx, _, keeper := keep.CreateTestInput(t, false, 1000)
pool := keeper.GetPool(ctx)
pool.UnbondedTokens = 1
pool.UnbondedShares = sdk.OneRat()
params := keeper.GetParams(ctx)
var delegations []Delegation
validators := []Validator{
NewValidator(keep.Addrs[0], keep.PKs[0], Description{Moniker: "hoop"}),
}
genesisState := types.NewGenesisState(pool, params, validators, delegations)
err := InitGenesis(ctx, keeper, genesisState)
require.Error(t, err)
validators[0].PoolShares.Amount = sdk.OneRat()
validators[0].DelegatorShares = sdk.OneRat()
genesisState = types.NewGenesisState(pool, params, validators, delegations)
err = InitGenesis(ctx, keeper, genesisState)
require.NoError(t, err)
}