github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/staking/keeper/keeper_ibc_adapter.go (about) 1 package keeper 2 3 import ( 4 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/store/prefix" 5 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 6 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/query" 7 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking/types" 8 outtypes "github.com/fibonacci-chain/fbc/x/staking/types" 9 "google.golang.org/grpc/codes" 10 "google.golang.org/grpc/status" 11 ) 12 13 func (k Keeper) TrackHistoricalInfo(ctx sdk.Context) { 14 entryNum := k.HistoricalEntries(ctx) 15 16 // Prune store to ensure we only have parameter-defined historical entries. 17 // In most cases, this will involve removing a single historical entry. 18 // In the rare scenario when the historical entries gets reduced to a lower value k' 19 // from the original value k. k - k' entries must be deleted from the store. 20 // Since the entries to be deleted are always in a continuous range, we can iterate 21 // over the historical entries starting from the most recent version to be pruned 22 // and then return at the first empty entry. 23 for i := ctx.BlockHeight() - int64(entryNum); i >= 0; i-- { 24 _, found := k.GetHistoricalInfo(ctx, i) 25 if found { 26 k.DeleteHistoricalInfo(ctx, i) 27 } else { 28 break 29 } 30 } 31 32 // if there is no need to persist historicalInfo, return 33 if entryNum == 0 { 34 return 35 } 36 37 // Create HistoricalInfo struct 38 lastVals := k.GetLastValidators(ctx) 39 historicalEntry := outtypes.NewHistoricalInfo(ctx.BlockHeader(), lastVals) 40 41 // Set latest HistoricalInfo at current height 42 k.SetHistoricalInfo(ctx, ctx.BlockHeight(), historicalEntry) 43 } 44 45 // SetHistoricalInfo sets the historical info at a given height 46 func (k Keeper) SetHistoricalInfo(ctx sdk.Context, height int64, hi outtypes.HistoricalInfo) { 47 store := ctx.KVStore(k.storeKey) 48 key := types.GetHistoricalInfoKey(height) 49 50 value := outtypes.MustMarshalHistoricalInfo(k.cdcMarshl.GetCdc(), hi) 51 store.Set(key, value) 52 } 53 54 func (k Keeper) HistoricalEntries(ctx sdk.Context) (res uint32) { 55 k.paramstore.GetIfExists(ctx, types.KeyHistoricalEntries, &res) 56 if res == 0 { 57 res = 10000 58 k.paramstore.Set(ctx, types.KeyHistoricalEntries, &res) 59 } 60 return 61 } 62 63 // DeleteHistoricalInfo deletes the historical info at a given height 64 func (k Keeper) DeleteHistoricalInfo(ctx sdk.Context, height int64) { 65 store := ctx.KVStore(k.storeKey) 66 key := types.GetHistoricalInfoKey(height) 67 68 store.Delete(key) 69 } 70 71 // get the group of the bonded validators 72 func (k Keeper) GetLastValidators(ctx sdk.Context) (validators []outtypes.Validator) { 73 store := ctx.KVStore(k.storeKey) 74 75 // add the actual validator power sorted store 76 maxValidators := k.MaxValidators(ctx) 77 validators = make([]outtypes.Validator, maxValidators) 78 79 iterator := sdk.KVStorePrefixIterator(store, types.LastValidatorPowerKey) 80 defer iterator.Close() 81 82 i := 0 83 for ; iterator.Valid(); iterator.Next() { 84 85 // sanity check 86 if i >= int(maxValidators) { 87 panic("more validators than maxValidators found") 88 } 89 address := types.AddressFromLastValidatorPowerKey(iterator.Key()) 90 validator := k.mustGetValidator(ctx, address) 91 92 validators[i] = validator 93 i++ 94 } 95 return validators[:i] // trim 96 } 97 98 // GetHistoricalInfo gets the historical info at a given height 99 func (k Keeper) GetHistoricalInfo(ctx sdk.Context, height int64) (types.HistoricalInfo, bool) { 100 store := ctx.KVStore(k.storeKey) 101 key := types.GetHistoricalInfoKey(height) 102 103 value := store.Get(key) 104 if value == nil { 105 return types.HistoricalInfo{}, false 106 } 107 108 return types.MustUnmarshalHistoricalInfo(k.cdcMarshl.GetCdc(), value), true 109 } 110 111 func (k Keeper) GetAllDelegatorDelegations(ctx sdk.Context, delegator sdk.AccAddress) []types.Delegation { 112 delegations := make([]types.Delegation, 0) 113 114 store := ctx.KVStore(k.storeKey) 115 delegatorPrefixKey := types.GetDelegationsKey(delegator) 116 iterator := sdk.KVStorePrefixIterator(store, delegatorPrefixKey) //smallest to largest 117 defer iterator.Close() 118 119 i := 0 120 for ; iterator.Valid(); iterator.Next() { 121 delegation := types.MustUnmarshalDelegation(k.cdcMarshl.GetCdc(), iterator.Value()) 122 delegations = append(delegations, delegation) 123 i++ 124 } 125 126 return delegations 127 } 128 129 func (k Keeper) DelegatorDelegations(ctx sdk.Context, req *outtypes.QueryDelegatorDelegationsRequest) (*outtypes.QueryDelegatorDelegationsResponse, error) { 130 if req == nil { 131 return nil, status.Errorf(codes.InvalidArgument, "empty request") 132 } 133 134 if req.DelegatorAddr == "" { 135 return nil, status.Error(codes.InvalidArgument, "delegator address cannot be empty") 136 } 137 var delegations types.Delegations 138 139 delAddr, err := sdk.AccAddressFromBech32(req.DelegatorAddr) 140 if err != nil { 141 return nil, err 142 } 143 144 store := ctx.KVStore(k.storeKey) 145 delStore := prefix.NewStore(store, types.GetDelegationsKey(delAddr)) 146 pageRes, err := query.Paginate(delStore, req.Pagination, func(key []byte, value []byte) error { 147 delegation, err := types.UnmarshalDelegation(k.cdcMarshl.GetCdc(), value) 148 if err != nil { 149 return err 150 } 151 delegations = append(delegations, delegation) 152 return nil 153 }) 154 if err != nil { 155 return nil, status.Error(codes.Internal, err.Error()) 156 } 157 158 delegationResps, err := DelegationsToDelegationResponses(ctx, k, delegations) 159 if err != nil { 160 return nil, status.Error(codes.Internal, err.Error()) 161 } 162 163 return &outtypes.QueryDelegatorDelegationsResponse{DelegationResponses: delegationResps, Pagination: pageRes}, nil 164 165 }