package keeper import ( "context" "fmt" abci "git.cw.tr/mukan-network/mukan-consensus/abci/types" addresscodec "cosmossdk.io/core/address" storetypes "cosmossdk.io/core/store" "cosmossdk.io/log" "cosmossdk.io/math" "git.cw.tr/mukan-network/mukan-sdk/codec" sdk "git.cw.tr/mukan-network/mukan-sdk/types" "git.cw.tr/mukan-network/mukan-sdk/x/staking/types" ) // Implements ValidatorSet interface var _ types.ValidatorSet = Keeper{} // Implements DelegationSet interface var _ types.DelegationSet = Keeper{} // Keeper of the x/staking store type Keeper struct { storeService storetypes.KVStoreService cdc codec.BinaryCodec authKeeper types.AccountKeeper bankKeeper types.BankKeeper hooks types.StakingHooks authority string validatorAddressCodec addresscodec.Codec consensusAddressCodec addresscodec.Codec } // NewKeeper creates a new staking Keeper instance func NewKeeper( cdc codec.BinaryCodec, storeService storetypes.KVStoreService, ak types.AccountKeeper, bk types.BankKeeper, authority string, validatorAddressCodec addresscodec.Codec, consensusAddressCodec addresscodec.Codec, ) *Keeper { // ensure bonded and not bonded module accounts are set if addr := ak.GetModuleAddress(types.BondedPoolName); addr == nil { panic(fmt.Sprintf("%s module account has not been set", types.BondedPoolName)) } if addr := ak.GetModuleAddress(types.NotBondedPoolName); addr == nil { panic(fmt.Sprintf("%s module account has not been set", types.NotBondedPoolName)) } // ensure that authority is a valid AccAddress if _, err := ak.AddressCodec().StringToBytes(authority); err != nil { panic("authority is not a valid acc address") } if validatorAddressCodec == nil || consensusAddressCodec == nil { panic("validator and/or consensus address codec are nil") } return &Keeper{ storeService: storeService, cdc: cdc, authKeeper: ak, bankKeeper: bk, hooks: nil, authority: authority, validatorAddressCodec: validatorAddressCodec, consensusAddressCodec: consensusAddressCodec, } } // Logger returns a module-specific logger. func (k Keeper) Logger(ctx context.Context) log.Logger { sdkCtx := sdk.UnwrapSDKContext(ctx) return sdkCtx.Logger().With("module", "x/"+types.ModuleName) } // Hooks gets the hooks for staking *Keeper { func (k *Keeper) Hooks() types.StakingHooks { if k.hooks == nil { // return a no-op implementation if no hooks are set return types.MultiStakingHooks{} } return k.hooks } // SetHooks sets the validator hooks. In contrast to other receivers, this method must take a pointer due to nature // of the hooks interface and SDK start up sequence. func (k *Keeper) SetHooks(sh types.StakingHooks) { if k.hooks != nil { panic("cannot set validator hooks twice") } k.hooks = sh } // GetLastTotalPower loads the last total validator power. func (k Keeper) GetLastTotalPower(ctx context.Context) (math.Int, error) { store := k.storeService.OpenKVStore(ctx) bz, err := store.Get(types.LastTotalPowerKey) if err != nil { return math.ZeroInt(), err } if bz == nil { return math.ZeroInt(), nil } ip := sdk.IntProto{} err = k.cdc.Unmarshal(bz, &ip) if err != nil { return math.ZeroInt(), err } return ip.Int, nil } // SetLastTotalPower sets the last total validator power. func (k Keeper) SetLastTotalPower(ctx context.Context, power math.Int) error { store := k.storeService.OpenKVStore(ctx) bz, err := k.cdc.Marshal(&sdk.IntProto{Int: power}) if err != nil { return err } return store.Set(types.LastTotalPowerKey, bz) } // GetAuthority returns the x/staking module's authority. func (k Keeper) GetAuthority() string { return k.authority } // ValidatorAddressCodec returns the app validator address codec. func (k Keeper) ValidatorAddressCodec() addresscodec.Codec { return k.validatorAddressCodec } // ConsensusAddressCodec returns the app consensus address codec. func (k Keeper) ConsensusAddressCodec() addresscodec.Codec { return k.consensusAddressCodec } // SetValidatorUpdates sets the ABCI validator power updates for the current block. func (k Keeper) SetValidatorUpdates(ctx context.Context, valUpdates []abci.ValidatorUpdate) error { store := k.storeService.OpenKVStore(ctx) bz, err := k.cdc.Marshal(&types.ValidatorUpdates{Updates: valUpdates}) if err != nil { return err } return store.Set(types.ValidatorUpdatesKey, bz) } // GetValidatorUpdates returns the ABCI validator power updates within the current block. func (k Keeper) GetValidatorUpdates(ctx context.Context) ([]abci.ValidatorUpdate, error) { store := k.storeService.OpenKVStore(ctx) bz, err := store.Get(types.ValidatorUpdatesKey) if err != nil { return nil, err } var valUpdates types.ValidatorUpdates err = k.cdc.Unmarshal(bz, &valUpdates) if err != nil { return nil, err } return valUpdates.Updates, nil }