mukan-sdk/x/staking/keeper/genesis.go
Mukan Erkin Törük abb1ff956e
Some checks are pending
Build SimApp / build (amd64) (push) Waiting to run
Build SimApp / build (arm64) (push) Waiting to run
CodeQL / Analyze (push) Waiting to run
Build & Push / build (push) Waiting to run
Run Gosec / Gosec (push) Waiting to run
Lint / golangci-lint (push) Waiting to run
Checks dependencies and mocks generation / Check go mod tidy (push) Waiting to run
Checks dependencies and mocks generation / Check up to date mocks (push) Waiting to run
System Tests / setup (push) Waiting to run
System Tests / test-system (push) Blocked by required conditions
System Tests / test-system-legacy (push) Blocked by required conditions
Tests / Code Coverage / split-test-files (push) Waiting to run
Tests / Code Coverage / tests (00) (push) Blocked by required conditions
Tests / Code Coverage / tests (01) (push) Blocked by required conditions
Tests / Code Coverage / tests (02) (push) Blocked by required conditions
Tests / Code Coverage / tests (03) (push) Blocked by required conditions
Tests / Code Coverage / test-integration (push) Waiting to run
Tests / Code Coverage / test-e2e (push) Waiting to run
Tests / Code Coverage / repo-analysis (push) Blocked by required conditions
Tests / Code Coverage / test-sim-nondeterminism (push) Waiting to run
Tests / Code Coverage / test-clientv2 (push) Waiting to run
Tests / Code Coverage / test-core (push) Waiting to run
Tests / Code Coverage / test-depinject (push) Waiting to run
Tests / Code Coverage / test-errors (push) Waiting to run
Tests / Code Coverage / test-math (push) Waiting to run
Tests / Code Coverage / test-schema (push) Waiting to run
Tests / Code Coverage / test-collections (push) Waiting to run
Tests / Code Coverage / test-cosmovisor (push) Waiting to run
Tests / Code Coverage / test-confix (push) Waiting to run
Tests / Code Coverage / test-store (push) Waiting to run
Tests / Code Coverage / test-log (push) Waiting to run
Tests / Code Coverage / test-x-tx (push) Waiting to run
Tests / Code Coverage / test-x-nft (push) Waiting to run
Tests / Code Coverage / test-x-circuit (push) Waiting to run
Tests / Code Coverage / test-x-feegrant (push) Waiting to run
Tests / Code Coverage / test-x-evidence (push) Waiting to run
Tests / Code Coverage / test-x-upgrade (push) Waiting to run
Tests / Code Coverage / test-tools-benchmark (push) Waiting to run
refactor: complete sovereign stack cleanup — all github.com upstream refs purged
2026-05-11 03:46:06 +03:00

279 lines
7.7 KiB
Go

package keeper
import (
"context"
"fmt"
abci "git.cw.tr/mukan-network/mukan-consensus/abci/types"
"cosmossdk.io/math"
sdk "git.cw.tr/mukan-network/mukan-sdk/types"
"git.cw.tr/mukan-network/mukan-sdk/x/staking/types"
)
// InitGenesis sets the pool and parameters for the provided keeper. For each
// validator in data, it sets that validator in the keeper along with manually
// setting the indexes. In addition, it also sets any delegations found in
// data. Finally, it updates the bonded validators.
// Returns final validator set after applying all declaration and delegations
func (k Keeper) InitGenesis(ctx context.Context, data *types.GenesisState) (res []abci.ValidatorUpdate) {
bondedTokens := math.ZeroInt()
notBondedTokens := math.ZeroInt()
// We need to pretend to be "n blocks before genesis", where "n" is the
// validator update delay, so that e.g. slashing periods are correctly
// initialized for the validator set e.g. with a one-block offset - the
// first TM block is at height 1, so state updates applied from
// genesis.json are in block 0.
sdkCtx := sdk.UnwrapSDKContext(ctx)
sdkCtx = sdkCtx.WithBlockHeight(1 - sdk.ValidatorUpdateDelay)
ctx = sdkCtx
if err := k.SetParams(ctx, data.Params); err != nil {
panic(err)
}
if err := k.SetLastTotalPower(ctx, data.LastTotalPower); err != nil {
panic(err)
}
for _, validator := range data.Validators {
if err := k.SetValidator(ctx, validator); err != nil {
panic(err)
}
// Manually set indices for the first time
if err := k.SetValidatorByConsAddr(ctx, validator); err != nil {
panic(err)
}
if err := k.SetValidatorByPowerIndex(ctx, validator); err != nil {
panic(err)
}
// Call the creation hook if not exported
if !data.Exported {
valbz, err := k.ValidatorAddressCodec().StringToBytes(validator.GetOperator())
if err != nil {
panic(err)
}
if err := k.Hooks().AfterValidatorCreated(ctx, valbz); err != nil {
panic(err)
}
}
// update timeslice if necessary
if validator.IsUnbonding() {
if err := k.InsertUnbondingValidatorQueue(ctx, validator); err != nil {
panic(err)
}
}
switch validator.GetStatus() {
case types.Bonded:
bondedTokens = bondedTokens.Add(validator.GetTokens())
case types.Unbonding, types.Unbonded:
notBondedTokens = notBondedTokens.Add(validator.GetTokens())
default:
panic("invalid validator status")
}
}
for _, delegation := range data.Delegations {
delegatorAddress, err := k.authKeeper.AddressCodec().StringToBytes(delegation.DelegatorAddress)
if err != nil {
panic(fmt.Errorf("invalid delegator address: %w", err))
}
valAddr, err := k.validatorAddressCodec.StringToBytes(delegation.GetValidatorAddr())
if err != nil {
panic(err)
}
// Call the before-creation hook if not exported
if !data.Exported {
if err := k.Hooks().BeforeDelegationCreated(ctx, delegatorAddress, valAddr); err != nil {
panic(err)
}
}
if err := k.SetDelegation(ctx, delegation); err != nil {
panic(err)
}
// Call the after-modification hook if not exported
if !data.Exported {
if err := k.Hooks().AfterDelegationModified(ctx, delegatorAddress, valAddr); err != nil {
panic(err)
}
}
}
for _, ubd := range data.UnbondingDelegations {
if err := k.SetUnbondingDelegation(ctx, ubd); err != nil {
panic(err)
}
for _, entry := range ubd.Entries {
if err := k.InsertUBDQueue(ctx, ubd, entry.CompletionTime); err != nil {
panic(err)
}
notBondedTokens = notBondedTokens.Add(entry.Balance)
}
}
for _, red := range data.Redelegations {
if err := k.SetRedelegation(ctx, red); err != nil {
panic(err)
}
for _, entry := range red.Entries {
if err := k.InsertRedelegationQueue(ctx, red, entry.CompletionTime); err != nil {
panic(err)
}
}
}
bondedCoins := sdk.NewCoins(sdk.NewCoin(data.Params.BondDenom, bondedTokens))
notBondedCoins := sdk.NewCoins(sdk.NewCoin(data.Params.BondDenom, notBondedTokens))
// check if the unbonded and bonded pools accounts exists
bondedPool := k.GetBondedPool(ctx)
if bondedPool == nil {
panic(fmt.Sprintf("%s module account has not been set", types.BondedPoolName))
}
// TODO: remove with genesis 2-phases refactor https://git.cw.tr/mukan-network/mukan-sdk/issues/2862
bondedBalance := k.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())
if bondedBalance.IsZero() {
k.authKeeper.SetModuleAccount(ctx, bondedPool)
}
// if balance is different from bonded coins panic because genesis is most likely malformed
if !bondedBalance.Equal(bondedCoins) {
panic(fmt.Sprintf("bonded pool balance is different from bonded coins: %s <-> %s", bondedBalance, bondedCoins))
}
notBondedPool := k.GetNotBondedPool(ctx)
if notBondedPool == nil {
panic(fmt.Sprintf("%s module account has not been set", types.NotBondedPoolName))
}
notBondedBalance := k.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress())
if notBondedBalance.IsZero() {
k.authKeeper.SetModuleAccount(ctx, notBondedPool)
}
// If balance is different from non bonded coins panic because genesis is most
// likely malformed.
if !notBondedBalance.Equal(notBondedCoins) {
panic(fmt.Sprintf("not bonded pool balance is different from not bonded coins: %s <-> %s", notBondedBalance, notBondedCoins))
}
// don't need to run CometBFT updates if we exported
if data.Exported {
for _, lv := range data.LastValidatorPowers {
valAddr, err := k.validatorAddressCodec.StringToBytes(lv.Address)
if err != nil {
panic(err)
}
err = k.SetLastValidatorPower(ctx, valAddr, lv.Power)
if err != nil {
panic(err)
}
validator, err := k.GetValidator(ctx, valAddr)
if err != nil {
panic(fmt.Sprintf("validator %s not found", lv.Address))
}
update := validator.ABCIValidatorUpdate(k.PowerReduction(ctx))
update.Power = lv.Power // keep the next-val-set offset, use the last power for the first block
res = append(res, update)
}
} else {
var err error
res, err = k.ApplyAndReturnValidatorSetUpdates(ctx)
if err != nil {
panic(err)
}
}
return res
}
// ExportGenesis returns a GenesisState for a given context and keeper. The
// GenesisState will contain the pool, params, validators, and bonds found in
// the keeper.
func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState {
var unbondingDelegations []types.UnbondingDelegation
err := k.IterateUnbondingDelegations(ctx, func(_ int64, ubd types.UnbondingDelegation) (stop bool) {
unbondingDelegations = append(unbondingDelegations, ubd)
return false
})
if err != nil {
panic(err)
}
var redelegations []types.Redelegation
err = k.IterateRedelegations(ctx, func(_ int64, red types.Redelegation) (stop bool) {
redelegations = append(redelegations, red)
return false
})
if err != nil {
panic(err)
}
var lastValidatorPowers []types.LastValidatorPower
err = k.IterateLastValidatorPowers(ctx, func(addr sdk.ValAddress, power int64) (stop bool) {
addrStr, err := k.validatorAddressCodec.BytesToString(addr)
if err != nil {
panic(err)
}
lastValidatorPowers = append(lastValidatorPowers, types.LastValidatorPower{Address: addrStr, Power: power})
return false
})
if err != nil {
panic(err)
}
params, err := k.GetParams(ctx)
if err != nil {
panic(err)
}
totalPower, err := k.GetLastTotalPower(ctx)
if err != nil {
panic(err)
}
allDelegations, err := k.GetAllDelegations(ctx)
if err != nil {
panic(err)
}
allValidators, err := k.GetAllValidators(ctx)
if err != nil {
panic(err)
}
return &types.GenesisState{
Params: params,
LastTotalPower: totalPower,
LastValidatorPowers: lastValidatorPowers,
Validators: allValidators,
Delegations: allDelegations,
UnbondingDelegations: unbondingDelegations,
Redelegations: redelegations,
Exported: true,
}
}