func (gs GenesisState) Validate() error {
	validClients := make(map[string]string)
	for i, client := range gs.Clients {
		if err := host.ClientIdentifierValidator(client.ChainName); err != nil {
			return fmt.Errorf("invalid client consensus state identifier %s index %d: %w", client.ChainName, i, err)
		}
		clientState, ok := client.ClientState.GetCachedValue().(exported.ClientState)
		if !ok {
			return fmt.Errorf("invalid client state with ID %s", client.ChainName)
		}
		if err := clientState.Validate(); err != nil {
			return fmt.Errorf("invalid client %v index %d: %w", client, i, err)
		}
		validClients[client.ChainName] = clientState.ClientType()
	}
	for _, cc := range gs.ClientsConsensus {
		clientType, ok := validClients[cc.ChainName]
		if !ok {
			return fmt.Errorf("consensus state in genesis has a chain name %s that does not map to a genesis client", cc.ChainName)
		}
		for i, consensusState := range cc.ConsensusStates {
			if consensusState.Height.IsZero() {
				return fmt.Errorf("consensus state height cannot be zero")
			}
			cs, ok := consensusState.ConsensusState.GetCachedValue().(exported.ConsensusState)
			if !ok {
				return fmt.Errorf("invalid consensus state with client ID %s at height %s", cc.ChainName, consensusState.Height)
			}
			if err := cs.ValidateBasic(); err != nil {
				return fmt.Errorf("invalid client consensus state %v chainName %s index %d: %w", cs, cc.ChainName, i, err)
			}
			if clientType != cs.ClientType() {
				return fmt.Errorf("consensus state client type %s does not equal client state client type %s", cs.ClientType(), clientType)
			}
		}
	}
	for _, clientMetadata := range gs.ClientsMetadata {
		_, ok := validClients[clientMetadata.ChainName]
		if !ok {
			return fmt.Errorf("metadata in genesis has a chain name %s that does not map to a genesis client", clientMetadata.ChainName)
		}
		for i, gm := range clientMetadata.Metadata {
			if err := gm.Validate(); err != nil {
				return fmt.Errorf("invalid client metadata %v chainName %s index %d: %w", gm, clientMetadata.ChainName, i, err)
			}
		}
	}
	if err := host.ClientIdentifierValidator(gs.NativeChainName); err != nil {
		return err
	}
	return nil
}
Validate performs basic genesis state validation returning an error upon any
failure.
package types
import (
	"fmt"
	"sort"
	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
	host "github.com/bianjieai/tibc-go/modules/tibc/core/24-host"
	"github.com/bianjieai/tibc-go/modules/tibc/core/exported"
)
var (
	_ codectypes.UnpackInterfacesMessage = IdentifiedClientState{}
	_ codectypes.UnpackInterfacesMessage = ClientsConsensusStates{}
	_ codectypes.UnpackInterfacesMessage = ClientConsensusStates{}
	_ codectypes.UnpackInterfacesMessage = GenesisState{}
)
var (
	_              sort.Interface           = ClientsConsensusStates{}
	_              exported.GenesisMetadata = GenesisMetadata{}
	defaultGenesis                          = GenesisState{
		Clients:          []IdentifiedClientState{},
		ClientsConsensus: ClientsConsensusStates{},
		NativeChainName:  "tibc-test",
	}
)
type ClientsConsensusStates []ClientConsensusStates
func (ccs ClientsConsensusStates) Len() int { return len(ccs) }
func (ccs ClientsConsensusStates) Less(i, j int) bool { return ccs[i].ChainName < ccs[j].ChainName }
func (ccs ClientsConsensusStates) Swap(i, j int) { ccs[i], ccs[j] = ccs[j], ccs[i] }
func (ccs ClientsConsensusStates) Sort() ClientsConsensusStates {
	sort.Sort(ccs)
	return ccs
}
func (ccs ClientsConsensusStates) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
	for _, clientConsensus := range ccs {
		if err := clientConsensus.UnpackInterfaces(unpacker); err != nil {
			return err
		}
	}
	return nil
}
func NewClientConsensusStates(chainName string, consensusStates []ConsensusStateWithHeight) ClientConsensusStates {
	return ClientConsensusStates{
		ChainName:       chainName,
		ConsensusStates: consensusStates,
	}
}
func (ccs ClientConsensusStates) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
	for _, consStateWithHeight := range ccs.ConsensusStates {
		if err := consStateWithHeight.UnpackInterfaces(unpacker); err != nil {
			return err
		}
	}
	return nil
}
func NewGenesisState(
	clients []IdentifiedClientState,
	clientsConsensus ClientsConsensusStates,
	clientsMetadata []IdentifiedGenesisMetadata,
	nativeChainName string,
) GenesisState {
	return GenesisState{
		Clients:          clients,
		ClientsConsensus: clientsConsensus,
		ClientsMetadata:  clientsMetadata,
		NativeChainName:  nativeChainName,
	}
}
func DefaultGenesisState() GenesisState {
	return defaultGenesis
}
func SetDefaultGenesisState(genesis GenesisState) {
	defaultGenesis = genesis
}
func (gs GenesisState) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
	for _, client := range gs.Clients {
		if err := client.UnpackInterfaces(unpacker); err != nil {
			return err
		}
	}
	return gs.ClientsConsensus.UnpackInterfaces(unpacker)
}