github.com/cosmos/cosmos-sdk@v0.50.10/x/staking/keeper/genesis.go (about) 1 package keeper 2 3 import ( 4 "context" 5 "fmt" 6 7 abci "github.com/cometbft/cometbft/abci/types" 8 9 "cosmossdk.io/math" 10 11 sdk "github.com/cosmos/cosmos-sdk/types" 12 "github.com/cosmos/cosmos-sdk/x/staking/types" 13 ) 14 15 // InitGenesis sets the pool and parameters for the provided keeper. For each 16 // validator in data, it sets that validator in the keeper along with manually 17 // setting the indexes. In addition, it also sets any delegations found in 18 // data. Finally, it updates the bonded validators. 19 // Returns final validator set after applying all declaration and delegations 20 func (k Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) (res []abci.ValidatorUpdate) { 21 bondedTokens := math.ZeroInt() 22 notBondedTokens := math.ZeroInt() 23 24 // We need to pretend to be "n blocks before genesis", where "n" is the 25 // validator update delay, so that e.g. slashing periods are correctly 26 // initialized for the validator set e.g. with a one-block offset - the 27 // first TM block is at height 1, so state updates applied from 28 // genesis.json are in block 0. 29 sdkCtx := sdk.UnwrapSDKContext(ctx) 30 sdkCtx = sdkCtx.WithBlockHeight(1 - sdk.ValidatorUpdateDelay) 31 ctx = sdkCtx 32 33 if err := k.SetParams(ctx, data.Params); err != nil { 34 panic(err) 35 } 36 37 if err := k.SetLastTotalPower(ctx, data.LastTotalPower); err != nil { 38 panic(err) 39 } 40 41 for _, validator := range data.Validators { 42 if err := k.SetValidator(ctx, validator); err != nil { 43 panic(err) 44 } 45 46 // Manually set indices for the first time 47 if err := k.SetValidatorByConsAddr(ctx, validator); err != nil { 48 panic(err) 49 } 50 51 if err := k.SetValidatorByPowerIndex(ctx, validator); err != nil { 52 panic(err) 53 } 54 55 // Call the creation hook if not exported 56 if !data.Exported { 57 valbz, err := k.ValidatorAddressCodec().StringToBytes(validator.GetOperator()) 58 if err != nil { 59 panic(err) 60 } 61 if err := k.Hooks().AfterValidatorCreated(ctx, valbz); err != nil { 62 panic(err) 63 } 64 } 65 66 // update timeslice if necessary 67 if validator.IsUnbonding() { 68 if err := k.InsertUnbondingValidatorQueue(ctx, validator); err != nil { 69 panic(err) 70 } 71 } 72 73 switch validator.GetStatus() { 74 case types.Bonded: 75 bondedTokens = bondedTokens.Add(validator.GetTokens()) 76 77 case types.Unbonding, types.Unbonded: 78 notBondedTokens = notBondedTokens.Add(validator.GetTokens()) 79 80 default: 81 panic("invalid validator status") 82 } 83 } 84 85 for _, delegation := range data.Delegations { 86 delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(delegation.DelegatorAddress) 87 if err != nil { 88 panic(fmt.Errorf("invalid delegator address: %s", err)) 89 } 90 91 valAddr, err := k.validatorAddressCodec.StringToBytes(delegation.GetValidatorAddr()) 92 if err != nil { 93 panic(err) 94 } 95 96 // Call the before-creation hook if not exported 97 if !data.Exported { 98 if err := k.Hooks().BeforeDelegationCreated(ctx, delegatorAddress, valAddr); err != nil { 99 panic(err) 100 } 101 } 102 103 if err := k.SetDelegation(ctx, delegation); err != nil { 104 panic(err) 105 } 106 107 // Call the after-modification hook if not exported 108 if !data.Exported { 109 if err := k.Hooks().AfterDelegationModified(ctx, delegatorAddress, valAddr); err != nil { 110 panic(err) 111 } 112 } 113 } 114 115 for _, ubd := range data.UnbondingDelegations { 116 if err := k.SetUnbondingDelegation(ctx, ubd); err != nil { 117 panic(err) 118 } 119 120 for _, entry := range ubd.Entries { 121 if err := k.InsertUBDQueue(ctx, ubd, entry.CompletionTime); err != nil { 122 panic(err) 123 } 124 notBondedTokens = notBondedTokens.Add(entry.Balance) 125 } 126 } 127 128 for _, red := range data.Redelegations { 129 if err := k.SetRedelegation(ctx, red); err != nil { 130 panic(err) 131 } 132 133 for _, entry := range red.Entries { 134 if err := k.InsertRedelegationQueue(ctx, red, entry.CompletionTime); err != nil { 135 panic(err) 136 } 137 } 138 } 139 140 bondedCoins := sdk.NewCoins(sdk.NewCoin(data.Params.BondDenom, bondedTokens)) 141 notBondedCoins := sdk.NewCoins(sdk.NewCoin(data.Params.BondDenom, notBondedTokens)) 142 143 // check if the unbonded and bonded pools accounts exists 144 bondedPool := k.GetBondedPool(ctx) 145 if bondedPool == nil { 146 panic(fmt.Sprintf("%s module account has not been set", types.BondedPoolName)) 147 } 148 149 // TODO: remove with genesis 2-phases refactor https://github.com/cosmos/cosmos-sdk/issues/2862 150 151 bondedBalance := k.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) 152 if bondedBalance.IsZero() { 153 k.authKeeper.SetModuleAccount(ctx, bondedPool) 154 } 155 156 // if balance is different from bonded coins panic because genesis is most likely malformed 157 if !bondedBalance.Equal(bondedCoins) { 158 panic(fmt.Sprintf("bonded pool balance is different from bonded coins: %s <-> %s", bondedBalance, bondedCoins)) 159 } 160 161 notBondedPool := k.GetNotBondedPool(ctx) 162 if notBondedPool == nil { 163 panic(fmt.Sprintf("%s module account has not been set", types.NotBondedPoolName)) 164 } 165 166 notBondedBalance := k.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) 167 if notBondedBalance.IsZero() { 168 k.authKeeper.SetModuleAccount(ctx, notBondedPool) 169 } 170 171 // If balance is different from non bonded coins panic because genesis is most 172 // likely malformed. 173 if !notBondedBalance.Equal(notBondedCoins) { 174 panic(fmt.Sprintf("not bonded pool balance is different from not bonded coins: %s <-> %s", notBondedBalance, notBondedCoins)) 175 } 176 177 // don't need to run CometBFT updates if we exported 178 if data.Exported { 179 for _, lv := range data.LastValidatorPowers { 180 valAddr, err := k.validatorAddressCodec.StringToBytes(lv.Address) 181 if err != nil { 182 panic(err) 183 } 184 185 err = k.SetLastValidatorPower(ctx, valAddr, lv.Power) 186 if err != nil { 187 panic(err) 188 } 189 190 validator, err := k.GetValidator(ctx, valAddr) 191 if err != nil { 192 panic(fmt.Sprintf("validator %s not found", lv.Address)) 193 } 194 195 update := validator.ABCIValidatorUpdate(k.PowerReduction(ctx)) 196 update.Power = lv.Power // keep the next-val-set offset, use the last power for the first block 197 res = append(res, update) 198 } 199 } else { 200 var err error 201 202 res, err = k.ApplyAndReturnValidatorSetUpdates(ctx) 203 if err != nil { 204 panic(err) 205 } 206 } 207 208 return res 209 } 210 211 // ExportGenesis returns a GenesisState for a given context and keeper. The 212 // GenesisState will contain the pool, params, validators, and bonds found in 213 // the keeper. 214 func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { 215 var unbondingDelegations []types.UnbondingDelegation 216 217 err := k.IterateUnbondingDelegations(ctx, func(_ int64, ubd types.UnbondingDelegation) (stop bool) { 218 unbondingDelegations = append(unbondingDelegations, ubd) 219 return false 220 }) 221 if err != nil { 222 panic(err) 223 } 224 225 var redelegations []types.Redelegation 226 227 err = k.IterateRedelegations(ctx, func(_ int64, red types.Redelegation) (stop bool) { 228 redelegations = append(redelegations, red) 229 return false 230 }) 231 if err != nil { 232 panic(err) 233 } 234 235 var lastValidatorPowers []types.LastValidatorPower 236 237 err = k.IterateLastValidatorPowers(ctx, func(addr sdk.ValAddress, power int64) (stop bool) { 238 addrStr, err := k.validatorAddressCodec.BytesToString(addr) 239 if err != nil { 240 panic(err) 241 } 242 lastValidatorPowers = append(lastValidatorPowers, types.LastValidatorPower{Address: addrStr, Power: power}) 243 return false 244 }) 245 if err != nil { 246 panic(err) 247 } 248 249 params, err := k.GetParams(ctx) 250 if err != nil { 251 panic(err) 252 } 253 254 totalPower, err := k.GetLastTotalPower(ctx) 255 if err != nil { 256 panic(err) 257 } 258 259 allDelegations, err := k.GetAllDelegations(ctx) 260 if err != nil { 261 panic(err) 262 } 263 264 allValidators, err := k.GetAllValidators(ctx) 265 if err != nil { 266 panic(err) 267 } 268 269 return &types.GenesisState{ 270 Params: params, 271 LastTotalPower: totalPower, 272 LastValidatorPowers: lastValidatorPowers, 273 Validators: allValidators, 274 Delegations: allDelegations, 275 UnbondingDelegations: unbondingDelegations, 276 Redelegations: redelegations, 277 Exported: true, 278 } 279 }