-
Notifications
You must be signed in to change notification settings - Fork 107
/
genesis.go
130 lines (118 loc) · 4.95 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
package types
import (
"bytes"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
ibctmtypes "github.com/cosmos/ibc-go/v3/modules/light-clients/07-tendermint/types"
ccv "github.com/cosmos/interchain-security/x/ccv/types"
abci "github.com/tendermint/tendermint/abci/types"
tmtypes "github.com/tendermint/tendermint/types"
)
// NewInitialGenesisState returns a consumer GenesisState for a completely new consumer chain.
func NewInitialGenesisState(cs *ibctmtypes.ClientState, consState *ibctmtypes.ConsensusState,
initValSet []abci.ValidatorUpdate, slashRequests SlashRequests, params Params) *GenesisState {
return &GenesisState{
Params: params,
NewChain: true,
ProviderClientState: cs,
ProviderConsensusState: consState,
InitialValSet: initValSet,
PendingSlashRequests: slashRequests,
}
}
// NewRestartGenesisState returns a consumer GenesisState that has already been established.
func NewRestartGenesisState(clientID, channelID string,
maturingPackets []MaturingVSCPacket,
initValSet []abci.ValidatorUpdate,
heightToValsetUpdateIDs []HeightToValsetUpdateID,
outstandingDowntimes []OutstandingDowntime,
params Params,
) *GenesisState {
return &GenesisState{
Params: params,
ProviderClientId: clientID,
ProviderChannelId: channelID,
MaturingPackets: maturingPackets,
NewChain: false,
InitialValSet: initValSet,
HeightToValsetUpdateId: heightToValsetUpdateIDs,
OutstandingDowntimeSlashing: outstandingDowntimes,
}
}
// DefaultGenesisState returns a default disabled consumer chain genesis state. This allows the module to be hooked up to app without getting use
// unless explicitly specified in genesis.
func DefaultGenesisState() *GenesisState {
return &GenesisState{
Params: DefaultParams(),
}
}
// Validate performs basic genesis state validation returning an error upon any failure.
func (gs GenesisState) Validate() error {
if !gs.Params.Enabled {
return nil
}
if len(gs.InitialValSet) == 0 {
return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "initial validator set is empty")
}
if err := gs.Params.Validate(); err != nil {
return err
}
if gs.NewChain {
if gs.ProviderClientState == nil {
return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider client state cannot be nil for new chain")
}
if err := gs.ProviderClientState.Validate(); err != nil {
return sdkerrors.Wrapf(ccv.ErrInvalidGenesis, "provider client state invalid for new chain %s", err.Error())
}
if gs.ProviderConsensusState == nil {
return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider consensus state cannot be nil for new chain")
}
if err := gs.ProviderConsensusState.ValidateBasic(); err != nil {
return sdkerrors.Wrapf(ccv.ErrInvalidGenesis, "provider consensus state invalid for new chain %s", err.Error())
}
if gs.ProviderClientId != "" {
return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider client id cannot be set for new chain. It must be established on handshake")
}
if gs.ProviderChannelId != "" {
return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider channel id cannot be set for new chain. It must be established on handshake")
}
if len(gs.MaturingPackets) != 0 {
return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "maturing packets must be empty for new chain")
}
// ensure that initial validator set is same as initial consensus state on provider client.
// this will be verified by provider module on channel handshake.
vals, err := tmtypes.PB2TM.ValidatorUpdates(gs.InitialValSet)
if err != nil {
return sdkerrors.Wrap(err, "could not convert val updates to validator set")
}
valSet := tmtypes.NewValidatorSet(vals)
if !bytes.Equal(gs.ProviderConsensusState.NextValidatorsHash, valSet.Hash()) {
return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "initial validators does not hash to NextValidatorsHash on provider client")
}
} else {
// NOTE: For restart genesis, we will verify initial validator set in InitGenesis.
if gs.ProviderClientId == "" {
return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider client id must be set for a restarting consumer genesis state")
}
if gs.ProviderChannelId == "" {
return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider channel id must be set for a restarting consumer genesis state")
}
if gs.ProviderClientState != nil || gs.ProviderConsensusState != nil {
return sdkerrors.Wrap(ccv.ErrInvalidGenesis, "provider client state and consensus states must be nil for a restarting genesis state")
}
for _, mat := range gs.MaturingPackets {
if err := mat.Validate(); err != nil {
return sdkerrors.Wrap(err, "invalid unbonding sequences")
}
}
}
return nil
}
func (mat MaturingVSCPacket) Validate() error {
if mat.MaturityTime == 0 {
return sdkerrors.Wrap(ccv.ErrInvalidVSCMaturedTime, "cannot have 0 maturity time")
}
if mat.VscId == 0 {
return sdkerrors.Wrap(ccv.ErrInvalidVSCMaturedId, "cannot have 0 maturity time")
}
return nil
}