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  }