Merge PR #1612: prevent zero power validators at genesis
This commit is contained in:
commit
efa003db9a
|
@ -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
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
||||
|
|
|
@ -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{}
|
||||
}
|
||||
|
|
|
@ -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{}
|
||||
}
|
||||
|
|
|
@ -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{}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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{}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
Loading…
Reference in New Issue