-
Notifications
You must be signed in to change notification settings - Fork 103
/
genesis.go
171 lines (147 loc) · 6.07 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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package keeper
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/interchain-security/v4/x/ccv/provider/types"
ccv "github.com/cosmos/interchain-security/v4/x/ccv/types"
)
// InitGenesis initializes the CCV provider state and binds to PortID.
func (k Keeper) InitGenesis(ctx sdk.Context, genState *types.GenesisState) {
k.SetPort(ctx, ccv.ProviderPortID)
// Only try to bind to port if it is not already bound, since we may already own
// port capability from capability InitGenesis
if !k.IsBound(ctx, ccv.ProviderPortID) {
// CCV module binds to the provider port on InitChain
// and claims the returned capability
err := k.BindPort(ctx, ccv.ProviderPortID)
if err != nil {
// If the binding fails, the chain MUST NOT start
panic(fmt.Errorf("could not claim port capability: %v", err))
}
}
k.SetValidatorSetUpdateId(ctx, genState.ValsetUpdateId)
for _, v2h := range genState.ValsetUpdateIdToHeight {
k.SetValsetUpdateBlockHeight(ctx, v2h.ValsetUpdateId, v2h.Height)
}
for _, prop := range genState.ConsumerAdditionProposals {
// prevent implicit memory aliasing
p := prop
k.SetPendingConsumerAdditionProp(ctx, &p)
}
for _, prop := range genState.ConsumerRemovalProposals {
p := prop
k.SetPendingConsumerRemovalProp(ctx, &p)
}
for _, ubdOp := range genState.UnbondingOps {
k.SetUnbondingOp(ctx, ubdOp)
}
// Note that MatureUnbondingOps aren't stored across blocks, but it
// might be used after implementing standalone to consumer transition
if genState.MatureUnbondingOps != nil {
k.AppendMaturedUnbondingOps(ctx, genState.MatureUnbondingOps.Ids)
}
// Set initial state for each consumer chain
for _, cs := range genState.ConsumerStates {
chainID := cs.ChainId
k.SetConsumerClientId(ctx, chainID, cs.ClientId)
if err := k.SetConsumerGenesis(ctx, chainID, cs.ConsumerGenesis); err != nil {
// An error here would indicate something is very wrong,
// the ConsumerGenesis validated in ConsumerState.Validate().
panic(fmt.Errorf("consumer chain genesis could not be persisted: %w", err))
}
for _, ubdOpIndex := range cs.UnbondingOpsIndex {
k.SetUnbondingOpIndex(ctx, chainID, ubdOpIndex.GetVscId(), ubdOpIndex.GetUnbondingOpIds())
}
// check if the CCV channel was established
if cs.ChannelId != "" {
k.SetChannelToChain(ctx, cs.ChannelId, chainID)
k.SetChainToChannel(ctx, chainID, cs.ChannelId)
k.SetInitChainHeight(ctx, chainID, cs.InitialHeight)
k.SetSlashAcks(ctx, cs.ChainId, cs.SlashDowntimeAck)
} else {
k.AppendPendingVSCPackets(ctx, chainID, cs.PendingValsetChanges...)
}
}
// Import key assignment state
for _, item := range genState.ValidatorConsumerPubkeys {
providerAddr := types.NewProviderConsAddress(item.ProviderAddr)
k.SetValidatorConsumerPubKey(ctx, item.ChainId, providerAddr, *item.ConsumerKey)
}
for _, item := range genState.ValidatorsByConsumerAddr {
consumerAddr := types.NewConsumerConsAddress(item.ConsumerAddr)
providerAddr := types.NewProviderConsAddress(item.ProviderAddr)
k.SetValidatorByConsumerAddr(ctx, item.ChainId, consumerAddr, providerAddr)
}
for _, item := range genState.ConsumerAddrsToPrune {
for _, addr := range item.ConsumerAddrs.Addresses {
consumerAddr := types.NewConsumerConsAddress(addr)
k.AppendConsumerAddrsToPrune(ctx, item.ChainId, item.VscId, consumerAddr)
}
}
for _, item := range genState.InitTimeoutTimestamps {
k.SetInitTimeoutTimestamp(ctx, item.ChainId, item.Timestamp)
}
for _, item := range genState.ExportedVscSendTimestamps {
for _, vscSendTimestamp := range item.VscSendTimestamps {
k.SetVscSendTimestamp(ctx, item.ChainId, vscSendTimestamp.VscId, vscSendTimestamp.Timestamp)
}
}
k.SetParams(ctx, genState.Params)
k.InitializeSlashMeter(ctx)
}
// ExportGenesis returns the CCV provider module's exported genesis
func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
// get a list of all registered consumer chains
registeredChains := k.GetAllConsumerChains(ctx)
var exportedVscSendTimestamps []types.ExportedVscSendTimestamp
// export states for each consumer chains
var consumerStates []types.ConsumerState
for _, chain := range registeredChains {
gen, found := k.GetConsumerGenesis(ctx, chain.ChainId)
if !found {
panic(fmt.Errorf("cannot find genesis for consumer chain %s with client %s", chain.ChainId, chain.ClientId))
}
// initial consumer chain states
cs := types.ConsumerState{
ChainId: chain.ChainId,
ClientId: chain.ClientId,
ConsumerGenesis: gen,
UnbondingOpsIndex: k.GetAllUnbondingOpIndexes(ctx, chain.ChainId),
}
// try to find channel id for the current consumer chain
channelId, found := k.GetChainToChannel(ctx, chain.ChainId)
if found {
cs.ChannelId = channelId
cs.InitialHeight, found = k.GetInitChainHeight(ctx, chain.ChainId)
if !found {
panic(fmt.Errorf("cannot find init height for consumer chain %s", chain.ChainId))
}
cs.SlashDowntimeAck = k.GetSlashAcks(ctx, chain.ChainId)
}
cs.PendingValsetChanges = k.GetPendingVSCPackets(ctx, chain.ChainId)
consumerStates = append(consumerStates, cs)
vscSendTimestamps := k.GetAllVscSendTimestamps(ctx, chain.ChainId)
exportedVscSendTimestamps = append(exportedVscSendTimestamps, types.ExportedVscSendTimestamp{ChainId: chain.ChainId, VscSendTimestamps: vscSendTimestamps})
}
// ConsumerAddrsToPrune are added only for registered consumer chains
consumerAddrsToPrune := []types.ConsumerAddrsToPrune{}
for _, chain := range registeredChains {
consumerAddrsToPrune = append(consumerAddrsToPrune, k.GetAllConsumerAddrsToPrune(ctx, chain.ChainId)...)
}
params := k.GetParams(ctx)
return types.NewGenesisState(
k.GetValidatorSetUpdateId(ctx),
k.GetAllValsetUpdateBlockHeights(ctx),
consumerStates,
k.GetAllUnbondingOps(ctx),
&types.MaturedUnbondingOps{Ids: k.GetMaturedUnbondingOps(ctx)},
k.GetAllPendingConsumerAdditionProps(ctx),
k.GetAllPendingConsumerRemovalProps(ctx),
params,
k.GetAllValidatorConsumerPubKeys(ctx, nil),
k.GetAllValidatorsByConsumerAddr(ctx, nil),
consumerAddrsToPrune,
k.GetAllInitTimeoutTimestamps(ctx),
exportedVscSendTimestamps,
)
}