-
Notifications
You must be signed in to change notification settings - Fork 3.6k
/
genesis.go
137 lines (114 loc) · 4.35 KB
/
genesis.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package types
import (
"fmt"
"sort"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host"
"github.com/cosmos/cosmos-sdk/x/ibc/core/exported"
)
var (
_ codectypes.UnpackInterfacesMessage = IdentifiedClientState{}
_ codectypes.UnpackInterfacesMessage = ClientsConsensusStates{}
_ codectypes.UnpackInterfacesMessage = ClientConsensusStates{}
_ codectypes.UnpackInterfacesMessage = GenesisState{}
)
var _ sort.Interface = ClientsConsensusStates{}
// ClientsConsensusStates defines a slice of ClientConsensusStates that supports the sort interface
type ClientsConsensusStates []ClientConsensusStates
// Len implements sort.Interface
func (ccs ClientsConsensusStates) Len() int { return len(ccs) }
// Less implements sort.Interface
func (ccs ClientsConsensusStates) Less(i, j int) bool { return ccs[i].ClientId < ccs[j].ClientId }
// Swap implements sort.Interface
func (ccs ClientsConsensusStates) Swap(i, j int) { ccs[i], ccs[j] = ccs[j], ccs[i] }
// Sort is a helper function to sort the set of ClientsConsensusStates in place
func (ccs ClientsConsensusStates) Sort() ClientsConsensusStates {
sort.Sort(ccs)
return ccs
}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (ccs ClientsConsensusStates) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
for _, clientConsensus := range ccs {
if err := clientConsensus.UnpackInterfaces(unpacker); err != nil {
return err
}
}
return nil
}
// NewClientConsensusStates creates a new ClientConsensusStates instance.
func NewClientConsensusStates(clientID string, consensusStates []ConsensusStateWithHeight) ClientConsensusStates {
return ClientConsensusStates{
ClientId: clientID,
ConsensusStates: consensusStates,
}
}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (ccs ClientConsensusStates) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
for _, consStateWithHeight := range ccs.ConsensusStates {
if err := consStateWithHeight.UnpackInterfaces(unpacker); err != nil {
return err
}
}
return nil
}
// NewGenesisState creates a GenesisState instance.
func NewGenesisState(
clients []IdentifiedClientState, clientsConsensus ClientsConsensusStates, createLocalhost bool,
) GenesisState {
return GenesisState{
Clients: clients,
ClientsConsensus: clientsConsensus,
CreateLocalhost: createLocalhost,
}
}
// DefaultGenesisState returns the ibc client submodule's default genesis state.
func DefaultGenesisState() GenesisState {
return GenesisState{
Clients: []IdentifiedClientState{},
ClientsConsensus: ClientsConsensusStates{},
CreateLocalhost: true,
}
}
// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
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)
}
// Validate performs basic genesis state validation returning an error upon any
// failure.
func (gs GenesisState) Validate() error {
for i, client := range gs.Clients {
if err := host.ClientIdentifierValidator(client.ClientId); err != nil {
return fmt.Errorf("invalid client consensus state identifier %s index %d: %w", client.ClientId, i, err)
}
clientState, ok := client.ClientState.GetCachedValue().(exported.ClientState)
if !ok {
return fmt.Errorf("invalid client state with ID %s", client.ClientId)
}
if err := clientState.Validate(); err != nil {
return fmt.Errorf("invalid client %v index %d: %w", client, i, err)
}
}
for i, cc := range gs.ClientsConsensus {
if err := host.ClientIdentifierValidator(cc.ClientId); err != nil {
return fmt.Errorf("invalid client consensus state identifier %s index %d: %w", cc.ClientId, i, err)
}
for _, 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.ClientId, consensusState.Height)
}
if err := cs.ValidateBasic(); err != nil {
return fmt.Errorf("invalid client consensus state %v index %d: %w", cs, i, err)
}
}
}
return nil
}