github.com/cosmos/cosmos-sdk@v0.50.10/x/staking/genesis.go (about)

     1  package staking
     2  
     3  import (
     4  	"fmt"
     5  
     6  	cmttypes "github.com/cometbft/cometbft/types"
     7  
     8  	cryptocodec "github.com/cosmos/cosmos-sdk/crypto/codec"
     9  	sdk "github.com/cosmos/cosmos-sdk/types"
    10  	"github.com/cosmos/cosmos-sdk/x/staking/keeper"
    11  	"github.com/cosmos/cosmos-sdk/x/staking/types"
    12  )
    13  
    14  // WriteValidators returns a slice of bonded genesis validators.
    15  func WriteValidators(ctx sdk.Context, keeper *keeper.Keeper) (vals []cmttypes.GenesisValidator, returnErr error) {
    16  	err := keeper.IterateLastValidators(ctx, func(_ int64, validator types.ValidatorI) (stop bool) {
    17  		pk, err := validator.ConsPubKey()
    18  		if err != nil {
    19  			returnErr = err
    20  			return true
    21  		}
    22  		cmtPk, err := cryptocodec.ToCmtPubKeyInterface(pk)
    23  		if err != nil {
    24  			returnErr = err
    25  			return true
    26  		}
    27  
    28  		vals = append(vals, cmttypes.GenesisValidator{
    29  			Address: sdk.ConsAddress(cmtPk.Address()).Bytes(),
    30  			PubKey:  cmtPk,
    31  			Power:   validator.GetConsensusPower(keeper.PowerReduction(ctx)),
    32  			Name:    validator.GetMoniker(),
    33  		})
    34  
    35  		return false
    36  	})
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  
    41  	return
    42  }
    43  
    44  // ValidateGenesis validates the provided staking genesis state to ensure the
    45  // expected invariants holds. (i.e. params in correct bounds, no duplicate validators)
    46  func ValidateGenesis(data *types.GenesisState) error {
    47  	if err := validateGenesisStateValidators(data.Validators); err != nil {
    48  		return err
    49  	}
    50  
    51  	return data.Params.Validate()
    52  }
    53  
    54  func validateGenesisStateValidators(validators []types.Validator) error {
    55  	addrMap := make(map[string]bool, len(validators))
    56  
    57  	for i := 0; i < len(validators); i++ {
    58  		val := validators[i]
    59  		consPk, err := val.ConsPubKey()
    60  		if err != nil {
    61  			return err
    62  		}
    63  
    64  		strKey := string(consPk.Bytes())
    65  
    66  		if _, ok := addrMap[strKey]; ok {
    67  			consAddr, err := val.GetConsAddr()
    68  			if err != nil {
    69  				return err
    70  			}
    71  			return fmt.Errorf("duplicate validator in genesis state: moniker %v, address %v", val.Description.Moniker, consAddr)
    72  		}
    73  
    74  		if val.Jailed && val.IsBonded() {
    75  			consAddr, err := val.GetConsAddr()
    76  			if err != nil {
    77  				return err
    78  			}
    79  			return fmt.Errorf("validator is bonded and jailed in genesis state: moniker %v, address %v", val.Description.Moniker, consAddr)
    80  		}
    81  
    82  		if val.DelegatorShares.IsZero() && !val.IsUnbonding() {
    83  			return fmt.Errorf("bonded/unbonded genesis validator cannot have zero delegator shares, validator: %v", val)
    84  		}
    85  
    86  		addrMap[strKey] = true
    87  	}
    88  
    89  	return nil
    90  }