refactor(x/staking,genutil)!: use validatorUpdates (#19754)

Co-authored-by: chixiaoxiao <chixiaoxiao@gmail.com>
This commit is contained in:
Chi Xiao Wen
2024-03-19 19:48:56 +00:00
committed by GitHub
co-authored by chixiaoxiao
parent a1bfe5d285
commit bfa734ce8f
14 changed files with 121 additions and 147 deletions
+1
View File
@@ -92,6 +92,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#17335](https://github.com/cosmos/cosmos-sdk/pull/17335) Remove usage of `"cosmossdk.io/x/staking/types".Infraction_*` in favour of `"cosmossdk.io/api/cosmos/staking/v1beta1".Infraction_` in order to remove dependency between modules on staking
* [#17655](https://github.com/cosmos/cosmos-sdk/pull/17655) `QueryHistoricalInfo` was adjusted to return `HistoricalRecord` and marked `Hist` as deprecated.
* [#19414](https://github.com/cosmos/cosmos-sdk/pull/19414) Staking module takes an environment variable in `NewStakingKeeper` instead of individual services.
* [#19754](https://github.com/cosmos/cosmos-sdk/pull/19754) update to use `[]module.ValidatorUpdate` as return for `ApplyAndReturnValidatorSetUpdates`.
### State Breaking changes
+2 -3
View File
@@ -4,11 +4,10 @@ import (
"context"
"time"
abci "github.com/cometbft/cometbft/abci/types"
"cosmossdk.io/x/staking/types"
"github.com/cosmos/cosmos-sdk/telemetry"
"github.com/cosmos/cosmos-sdk/types/module"
)
// BeginBlocker will persist the current header and validator set as a historical entry
@@ -19,7 +18,7 @@ func (k *Keeper) BeginBlocker(ctx context.Context) error {
}
// EndBlocker called at every block, update validator set
func (k *Keeper) EndBlocker(ctx context.Context) ([]abci.ValidatorUpdate, error) {
func (k *Keeper) EndBlocker(ctx context.Context) ([]module.ValidatorUpdate, error) {
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker)
return k.BlockValidatorUpdates(ctx)
}
+7 -7
View File
@@ -4,13 +4,12 @@ import (
"context"
"fmt"
abci "github.com/cometbft/cometbft/abci/types"
"cosmossdk.io/collections"
"cosmossdk.io/math"
"cosmossdk.io/x/staking/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
)
// InitGenesis sets the pool and parameters for the provided keeper. For each
@@ -18,7 +17,7 @@ import (
// setting the indexes. In addition, it also sets any delegations found in
// data. Finally, it updates the bonded validators.
// Returns final validator set after applying all declaration and delegations
func (k Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) (res []abci.ValidatorUpdate, err error) {
func (k Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) ([]module.ValidatorUpdate, error) {
bondedTokens := math.ZeroInt()
notBondedTokens := math.ZeroInt()
@@ -176,6 +175,7 @@ func (k Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) (res
}
// don't need to run CometBFT updates if we exported
var moduleValidatorUpdates []module.ValidatorUpdate
if data.Exported {
for _, lv := range data.LastValidatorPowers {
valAddr, err := k.validatorAddressCodec.StringToBytes(lv.Address)
@@ -193,20 +193,20 @@ func (k Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) (res
return nil, fmt.Errorf("validator %s not found", lv.Address)
}
update := validator.ABCIValidatorUpdate(k.PowerReduction(ctx))
update := validator.ModuleValidatorUpdate(k.PowerReduction(ctx))
update.Power = lv.Power // keep the next-val-set offset, use the last power for the first block
res = append(res, update)
moduleValidatorUpdates = append(moduleValidatorUpdates, update)
}
} else {
var err error
res, err = k.ApplyAndReturnValidatorSetUpdates(ctx)
moduleValidatorUpdates, err = k.ApplyAndReturnValidatorSetUpdates(ctx)
if err != nil {
return nil, err
}
}
return res, nil
return moduleValidatorUpdates, nil
}
// ExportGenesis returns a GenesisState for a given context and keeper. The
+21 -5
View File
@@ -19,11 +19,12 @@ import (
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/module"
)
// BlockValidatorUpdates calculates the ValidatorUpdates for the current block
// Called in each EndBlock
func (k Keeper) BlockValidatorUpdates(ctx context.Context) ([]abci.ValidatorUpdate, error) {
func (k Keeper) BlockValidatorUpdates(ctx context.Context) ([]module.ValidatorUpdate, error) {
// Calculate validator set changes.
//
// NOTE: ApplyAndReturnValidatorSetUpdates has to come before
@@ -137,7 +138,7 @@ func (k Keeper) BlockValidatorUpdates(ctx context.Context) ([]abci.ValidatorUpda
// CONTRACT: Only validators with non-zero power or zero-power that were bonded
// at the previous block height or were removed from the validator set entirely
// are returned to CometBFT.
func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx context.Context) (updates []abci.ValidatorUpdate, err error) {
func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx context.Context) ([]module.ValidatorUpdate, error) {
params, err := k.Params.Get(ctx)
if err != nil {
return nil, err
@@ -162,6 +163,8 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx context.Context) (updates
}
defer iterator.Close()
var updates []abci.ValidatorUpdate
var moduleValidatorUpdates []module.ValidatorUpdate
for count := 0; iterator.Valid() && count < int(maxValidators); iterator.Next() {
// everything that is iterated in this loop is becoming or already a
// part of the bonded validator set
@@ -213,7 +216,7 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx context.Context) (updates
// update the validator set if power has changed
if !found || !bytes.Equal(oldPowerBytes, newPowerBytes) {
updates = append(updates, validator.ABCIValidatorUpdate(powerReduction))
moduleValidatorUpdates = append(moduleValidatorUpdates, validator.ModuleValidatorUpdate(powerReduction))
if err = k.SetLastValidatorPower(ctx, valAddr, newPower); err != nil {
return nil, err
}
@@ -249,6 +252,7 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx context.Context) (updates
}
updates = append(updates, validator.ABCIValidatorUpdateZero())
moduleValidatorUpdates = append(moduleValidatorUpdates, validator.ModuleValidatorUpdateZero())
}
// ApplyAndReturnValidatorSetUpdates checks if there is ConsPubKeyRotationHistory
@@ -281,7 +285,7 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx context.Context) (updates
newPk, ok := history.NewConsPubkey.GetCachedValue().(cryptotypes.PubKey)
if !ok {
return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidType, "Expecting cryptotypes.PubKey, got %T", oldPk)
return nil, errorsmod.Wrapf(sdkerrors.ErrInvalidType, "Expecting cryptotypes.PubKey, got %T", newPk)
}
newCmtPk, err := cryptocodec.ToCmtProtoPublicKey(newPk)
if err != nil {
@@ -297,11 +301,23 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx context.Context) (updates
Power: 0,
})
moduleValidatorUpdates = append(moduleValidatorUpdates, module.ValidatorUpdate{
PubKey: oldPk.Bytes(),
PubKeyType: oldPk.Type(),
Power: 0,
})
updates = append(updates, abci.ValidatorUpdate{
PubKey: newCmtPk,
Power: validator.ConsensusPower(powerReduction),
})
moduleValidatorUpdates = append(moduleValidatorUpdates, module.ValidatorUpdate{
PubKey: newPk.Bytes(),
PubKeyType: newPk.Type(),
Power: validator.ConsensusPower(powerReduction),
})
if err := k.updateToNewPubkey(ctx, validator, history.OldConsPubkey, history.NewConsPubkey, history.Fee); err != nil {
return nil, err
}
@@ -340,7 +356,7 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx context.Context) (updates
return nil, err
}
return updates, err
return moduleValidatorUpdates, err
}
// Validator state transitions
+10 -10
View File
@@ -3,7 +3,6 @@ package keeper_test
import (
"time"
abci "github.com/cometbft/cometbft/abci/types"
"github.com/golang/mock/gomock"
"cosmossdk.io/collections"
@@ -15,9 +14,10 @@ import (
stakingtypes "cosmossdk.io/x/staking/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/module"
)
func (s *KeeperTestSuite) applyValidatorSetUpdates(ctx sdk.Context, keeper *stakingkeeper.Keeper, expectedUpdatesLen int) []abci.ValidatorUpdate {
func (s *KeeperTestSuite) applyValidatorSetUpdates(ctx sdk.Context, keeper *stakingkeeper.Keeper, expectedUpdatesLen int) []module.ValidatorUpdate {
updates, err := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
s.Require().NoError(err)
if expectedUpdatesLen >= 0 {
@@ -49,7 +49,7 @@ func (s *KeeperTestSuite) TestValidator() {
updates := s.applyValidatorSetUpdates(ctx, keeper, 1)
validator, err := keeper.GetValidator(ctx, valAddr)
require.NoError(err)
require.Equal(validator.ABCIValidatorUpdate(keeper.PowerReduction(ctx)), updates[0])
require.Equal(validator.ModuleValidatorUpdate(keeper.PowerReduction(ctx)), updates[0])
// after the save the validator should be bonded
require.Equal(stakingtypes.Bonded, validator.Status)
@@ -321,8 +321,8 @@ func (s *KeeperTestSuite) TestApplyAndReturnValidatorSetUpdatesPowerDecrease() {
// CometBFT updates should reflect power change
updates := s.applyValidatorSetUpdates(ctx, keeper, 2)
require.Equal(validators[0].ABCIValidatorUpdate(keeper.PowerReduction(ctx)), updates[0])
require.Equal(validators[1].ABCIValidatorUpdate(keeper.PowerReduction(ctx)), updates[1])
require.Equal(validators[0].ModuleValidatorUpdate(keeper.PowerReduction(ctx)), updates[0])
require.Equal(validators[1].ModuleValidatorUpdate(keeper.PowerReduction(ctx)), updates[1])
}
func (s *KeeperTestSuite) TestUpdateValidatorCommission() {
@@ -514,7 +514,7 @@ func (s *KeeperTestSuite) TestValidatorConsPubKeyUpdate() {
updates := s.applyValidatorSetUpdates(ctx, keeper, 1)
validator, err := keeper.GetValidator(ctx, valAddr)
require.NoError(err)
require.Equal(validator.ABCIValidatorUpdate(keeper.PowerReduction(ctx)), updates[0])
require.Equal(validator.ModuleValidatorUpdate(keeper.PowerReduction(ctx)), updates[0])
}
params, err := keeper.Params.Get(ctx)
@@ -542,17 +542,17 @@ func (s *KeeperTestSuite) TestValidatorConsPubKeyUpdate() {
updates := s.applyValidatorSetUpdates(ctx, keeper, 2)
originalPubKey, err := validators[0].CmtConsPublicKey()
originalPubKey, err := validators[0].ConsPubKey()
require.NoError(err)
validator, err := keeper.GetValidator(ctx, valAddr1)
require.NoError(err)
newPubKey, err := validator.CmtConsPublicKey()
newPubKey, err := validator.ConsPubKey()
require.NoError(err)
require.Equal(int64(0), updates[0].Power)
require.Equal(originalPubKey, updates[0].PubKey)
require.Equal(originalPubKey.Bytes(), updates[0].PubKey)
require.Equal(int64(10), updates[1].Power)
require.Equal(newPubKey, updates[1].PubKey)
require.Equal(newPubKey.Bytes(), updates[1].PubKey)
}
+2 -51
View File
@@ -147,33 +147,8 @@ func (am AppModule) ValidateGenesis(bz json.RawMessage) error {
// InitGenesis performs genesis initialization for the staking module.
func (am AppModule) InitGenesis(ctx context.Context, data json.RawMessage) ([]module.ValidatorUpdate, error) {
var genesisState types.GenesisState
am.cdc.MustUnmarshalJSON(data, &genesisState)
cometValidatorUpdates, err := am.keeper.InitGenesis(ctx, &genesisState) // TODO: refactor to return ValidatorUpdate higher up the stack
if err != nil {
return nil, err
}
validatorUpdates := make([]module.ValidatorUpdate, len(cometValidatorUpdates))
for i, v := range cometValidatorUpdates {
if ed25519 := v.PubKey.GetEd25519(); len(ed25519) > 0 {
validatorUpdates[i] = module.ValidatorUpdate{
PubKey: ed25519,
PubKeyType: "ed25519",
Power: v.Power,
}
} else if secp256k1 := v.PubKey.GetSecp256K1(); len(secp256k1) > 0 {
validatorUpdates[i] = module.ValidatorUpdate{
PubKey: secp256k1,
PubKeyType: "secp256k1",
Power: v.Power,
}
} else {
return nil, fmt.Errorf("unexpected validator pubkey type: %T", v.PubKey)
}
}
return validatorUpdates, nil
return am.keeper.InitGenesis(ctx, &genesisState)
}
// ExportGenesis returns the exported genesis state as raw bytes for the staking module.
@@ -199,29 +174,5 @@ func (am AppModule) BeginBlock(ctx context.Context) error {
// EndBlock returns the end blocker for the staking module.
func (am AppModule) EndBlock(ctx context.Context) ([]module.ValidatorUpdate, error) {
cometValidatorUpdates, err := am.keeper.EndBlocker(ctx) // TODO: refactor to return appmodule.ValidatorUpdate higher up the stack
if err != nil {
return nil, err
}
validatorUpdates := make([]module.ValidatorUpdate, len(cometValidatorUpdates))
for i, v := range cometValidatorUpdates {
if ed25519 := v.PubKey.GetEd25519(); len(ed25519) > 0 {
validatorUpdates[i] = module.ValidatorUpdate{
PubKey: ed25519,
PubKeyType: "ed25519",
Power: v.Power,
}
} else if secp256k1 := v.PubKey.GetSecp256K1(); len(secp256k1) > 0 {
validatorUpdates[i] = module.ValidatorUpdate{
PubKey: secp256k1,
PubKeyType: "secp256k1",
Power: v.Power,
}
} else {
return nil, fmt.Errorf("unexpected validator pubkey type: %T", v.PubKey)
}
}
return validatorUpdates, nil
return am.keeper.EndBlocker(ctx)
}
+31
View File
@@ -20,6 +20,7 @@ import (
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/module"
)
const (
@@ -270,6 +271,21 @@ func (v Validator) ABCIValidatorUpdate(r math.Int) abci.ValidatorUpdate {
}
}
// ModuleValidatorUpdate returns a module.ValidatorUpdate from a staking validator type
// with the full validator power
func (v Validator) ModuleValidatorUpdate(r math.Int) module.ValidatorUpdate {
consPk, err := v.ConsPubKey()
if err != nil {
panic(err)
}
return module.ValidatorUpdate{
PubKey: consPk.Bytes(),
PubKeyType: consPk.Type(),
Power: v.ConsensusPower(r),
}
}
// ABCIValidatorUpdateZero returns an abci.ValidatorUpdate from a staking validator type
// with zero power used for validator updates.
func (v Validator) ABCIValidatorUpdateZero() abci.ValidatorUpdate {
@@ -284,6 +300,21 @@ func (v Validator) ABCIValidatorUpdateZero() abci.ValidatorUpdate {
}
}
// ModuleValidatorUpdateZero returns a module.ValidatorUpdate from a staking validator type
// with zero power used for validator updates.
func (v Validator) ModuleValidatorUpdateZero() module.ValidatorUpdate {
consPk, err := v.ConsPubKey()
if err != nil {
panic(err)
}
return module.ValidatorUpdate{
PubKey: consPk.Bytes(),
PubKeyType: consPk.Type(),
Power: 0,
}
}
// SetInitialCommission attempts to set a validator's initial commission. An
// error is returned if the commission is invalid.
func (v Validator) SetInitialCommission(commission Commission) (Validator, error) {