github.com/Finschia/finschia-sdk@v0.48.1/x/slashing/keeper/signing_info.go (about) 1 package keeper 2 3 import ( 4 "time" 5 6 gogotypes "github.com/gogo/protobuf/types" 7 8 sdk "github.com/Finschia/finschia-sdk/types" 9 "github.com/Finschia/finschia-sdk/x/slashing/types" 10 ) 11 12 // GetValidatorSigningInfo retruns the ValidatorSigningInfo for a specific validator 13 // ConsAddress 14 func (k Keeper) GetValidatorSigningInfo(ctx sdk.Context, address sdk.ConsAddress) (info types.ValidatorSigningInfo, found bool) { 15 store := ctx.KVStore(k.storeKey) 16 bz := store.Get(types.ValidatorSigningInfoKey(address)) 17 if bz == nil { 18 found = false 19 return 20 } 21 k.cdc.MustUnmarshal(bz, &info) 22 found = true 23 return 24 } 25 26 // HasValidatorSigningInfo returns if a given validator has signing information 27 // persited. 28 func (k Keeper) HasValidatorSigningInfo(ctx sdk.Context, consAddr sdk.ConsAddress) bool { 29 _, ok := k.GetValidatorSigningInfo(ctx, consAddr) 30 return ok 31 } 32 33 // SetValidatorSigningInfo sets the validator signing info to a consensus address key 34 func (k Keeper) SetValidatorSigningInfo(ctx sdk.Context, address sdk.ConsAddress, info types.ValidatorSigningInfo) { 35 store := ctx.KVStore(k.storeKey) 36 bz := k.cdc.MustMarshal(&info) 37 store.Set(types.ValidatorSigningInfoKey(address), bz) 38 } 39 40 // IterateValidatorSigningInfos iterates over the stored ValidatorSigningInfo 41 func (k Keeper) IterateValidatorSigningInfos(ctx sdk.Context, 42 handler func(address sdk.ConsAddress, info types.ValidatorSigningInfo) (stop bool), 43 ) { 44 store := ctx.KVStore(k.storeKey) 45 iter := sdk.KVStorePrefixIterator(store, types.ValidatorSigningInfoKeyPrefix) 46 defer iter.Close() 47 for ; iter.Valid(); iter.Next() { 48 address := types.ValidatorSigningInfoAddress(iter.Key()) 49 var info types.ValidatorSigningInfo 50 k.cdc.MustUnmarshal(iter.Value(), &info) 51 if handler(address, info) { 52 break 53 } 54 } 55 } 56 57 // GetValidatorMissedBlockBitArray gets the bit for the missed blocks array 58 func (k Keeper) GetValidatorMissedBlockBitArray(ctx sdk.Context, address sdk.ConsAddress, index int64) bool { 59 store := ctx.KVStore(k.storeKey) 60 bz := store.Get(types.ValidatorMissedBlockBitArrayKey(address, index)) 61 var missed gogotypes.BoolValue 62 if bz == nil { 63 // lazy: treat empty key as not missed 64 return false 65 } 66 k.cdc.MustUnmarshal(bz, &missed) 67 68 return missed.Value 69 } 70 71 // IterateValidatorMissedBlockBitArray iterates over the signed blocks window 72 // and performs a callback function 73 func (k Keeper) IterateValidatorMissedBlockBitArray(ctx sdk.Context, 74 address sdk.ConsAddress, handler func(index int64, missed bool) (stop bool), 75 ) { 76 store := ctx.KVStore(k.storeKey) 77 index := int64(0) 78 // Array may be sparse 79 for ; index < k.SignedBlocksWindow(ctx); index++ { 80 var missed gogotypes.BoolValue 81 bz := store.Get(types.ValidatorMissedBlockBitArrayKey(address, index)) 82 if bz == nil { 83 continue 84 } 85 86 k.cdc.MustUnmarshal(bz, &missed) 87 if handler(index, missed.Value) { 88 break 89 } 90 } 91 } 92 93 // GetValidatorMissedBlocks returns array of missed blocks for given validator Cons address 94 func (k Keeper) GetValidatorMissedBlocks(ctx sdk.Context, address sdk.ConsAddress) []types.MissedBlock { 95 missedBlocks := []types.MissedBlock{} 96 k.IterateValidatorMissedBlockBitArray(ctx, address, func(index int64, missed bool) (stop bool) { 97 missedBlocks = append(missedBlocks, types.NewMissedBlock(index, missed)) 98 return false 99 }) 100 101 return missedBlocks 102 } 103 104 // JailUntil attempts to set a validator's JailedUntil attribute in its signing 105 // info. It will panic if the signing info does not exist for the validator. 106 func (k Keeper) JailUntil(ctx sdk.Context, consAddr sdk.ConsAddress, jailTime time.Time) { 107 signInfo, ok := k.GetValidatorSigningInfo(ctx, consAddr) 108 if !ok { 109 panic("cannot jail validator that does not have any signing information") 110 } 111 112 signInfo.JailedUntil = jailTime 113 k.SetValidatorSigningInfo(ctx, consAddr, signInfo) 114 } 115 116 // Tombstone attempts to tombstone a validator. It will panic if signing info for 117 // the given validator does not exist. 118 func (k Keeper) Tombstone(ctx sdk.Context, consAddr sdk.ConsAddress) { 119 signInfo, ok := k.GetValidatorSigningInfo(ctx, consAddr) 120 if !ok { 121 panic("cannot tombstone validator that does not have any signing information") 122 } 123 124 if signInfo.Tombstoned { 125 panic("cannot tombstone validator that is already tombstoned") 126 } 127 128 signInfo.Tombstoned = true 129 k.SetValidatorSigningInfo(ctx, consAddr, signInfo) 130 } 131 132 // IsTombstoned returns if a given validator by consensus address is tombstoned. 133 func (k Keeper) IsTombstoned(ctx sdk.Context, consAddr sdk.ConsAddress) bool { 134 signInfo, ok := k.GetValidatorSigningInfo(ctx, consAddr) 135 if !ok { 136 return false 137 } 138 139 return signInfo.Tombstoned 140 } 141 142 // SetValidatorMissedBlockBitArray sets the bit that checks if the validator has 143 // missed a block in the current window 144 func (k Keeper) SetValidatorMissedBlockBitArray(ctx sdk.Context, address sdk.ConsAddress, index int64, missed bool) { 145 store := ctx.KVStore(k.storeKey) 146 bz := k.cdc.MustMarshal(&gogotypes.BoolValue{Value: missed}) 147 store.Set(types.ValidatorMissedBlockBitArrayKey(address, index), bz) 148 } 149 150 // clearValidatorMissedBlockBitArray deletes every instance of ValidatorMissedBlockBitArray in the store 151 func (k Keeper) clearValidatorMissedBlockBitArray(ctx sdk.Context, address sdk.ConsAddress) { 152 store := ctx.KVStore(k.storeKey) 153 iter := sdk.KVStorePrefixIterator(store, types.ValidatorMissedBlockBitArrayPrefixKey(address)) 154 defer iter.Close() 155 for ; iter.Valid(); iter.Next() { 156 store.Delete(iter.Key()) 157 } 158 }