cosmos-sdk/x/slashing/keeper/infractions.go

127 lines
4.8 KiB
Go
Raw Normal View History

package keeper
2018-05-23 13:25:56 -07:00
import (
"fmt"
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
2018-05-23 13:25:56 -07:00
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/slashing/types"
2018-05-23 13:25:56 -07:00
)
// HandleValidatorSignature handles a validator signature, must be called once per validator per block.
func (k Keeper) HandleValidatorSignature(ctx sdk.Context, addr cryptotypes.Address, power int64, signed bool) {
logger := k.Logger(ctx)
2018-05-23 13:25:56 -07:00
height := ctx.BlockHeight()
// fetch the validator public key
consAddr := sdk.ConsAddress(addr)
if _, err := k.GetPubkey(ctx, addr); err != nil {
panic(fmt.Sprintf("Validator consensus-address %s not found", consAddr))
}
// fetch signing info
signInfo, found := k.GetValidatorSigningInfo(ctx, consAddr)
if !found {
panic(fmt.Sprintf("Expected signing info for validator %s but not found", consAddr))
}
// this is a relative index, so it counts blocks the validator *should* have signed
// will use the 0-value default signing info if not present, except for start height
index := signInfo.IndexOffset % k.SignedBlocksWindow(ctx)
signInfo.IndexOffset++
2018-05-28 15:10:52 -07:00
// Update signed block bit array & counter
2018-05-30 15:32:08 -07:00
// This counter just tracks the sum of the bit array
// That way we avoid needing to read/write the whole array each time
previous := k.GetValidatorMissedBlockBitArray(ctx, consAddr, index)
missed := !signed
2018-10-15 14:58:39 -07:00
switch {
case !previous && missed:
// Array value has changed from not missed to missed, increment counter
k.SetValidatorMissedBlockBitArray(ctx, consAddr, index, true)
signInfo.MissedBlocksCounter++
2018-10-15 14:58:39 -07:00
case previous && !missed:
// Array value has changed from missed to not missed, decrement counter
k.SetValidatorMissedBlockBitArray(ctx, consAddr, index, false)
signInfo.MissedBlocksCounter--
2018-10-15 14:58:39 -07:00
default:
// Array value at this index has not changed, no need to update counter
2018-05-23 13:25:56 -07:00
}
2018-05-28 15:10:52 -07:00
minSignedPerWindow := k.MinSignedPerWindow(ctx)
if missed {
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeLiveness,
sdk.NewAttribute(types.AttributeKeyAddress, consAddr.String()),
sdk.NewAttribute(types.AttributeKeyMissedBlocks, fmt.Sprintf("%d", signInfo.MissedBlocksCounter)),
sdk.NewAttribute(types.AttributeKeyHeight, fmt.Sprintf("%d", height)),
),
)
logger.Info(
"absent validator",
"height", height,
"validator", consAddr.String(),
"missed", signInfo.MissedBlocksCounter,
"threshold", minSignedPerWindow,
)
}
minHeight := signInfo.StartHeight + k.SignedBlocksWindow(ctx)
maxMissed := k.SignedBlocksWindow(ctx) - minSignedPerWindow
// if we are past the minimum height and the validator has missed too many blocks, punish them
2018-10-12 12:15:39 -07:00
if height > minHeight && signInfo.MissedBlocksCounter > maxMissed {
validator := k.sk.ValidatorByConsAddr(ctx, consAddr)
if validator != nil && !validator.IsJailed() {
2018-08-22 08:56:13 -07:00
// Downtime confirmed: slash and jail the validator
2018-09-06 21:56:05 -07:00
// We need to retrieve the stake distribution which signed the block, so we subtract ValidatorUpdateDelay from the evidence height,
// and subtract an additional 1 since this is the LastCommit.
2018-10-05 11:00:01 -07:00
// Note that this *can* result in a negative "distributionHeight" up to -ValidatorUpdateDelay-1,
// i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block.
// That's fine since this is just used to filter unbonding delegations & redelegations.
distributionHeight := height - sdk.ValidatorUpdateDelay - 1
Merge PR #4541: Events Tracking / Tendermint v0.32.0 Update * Update Tendermint to v0.32.0-dev0 * Initial refactor of tags * Update event types and add unit tests * Refactor context * Update module manager * Update result godoc * Implement ToABCIEvents * Update BaseApp * Minor cleanup * Fix typo * Update x/bank message handler * Update x/bank keeper * Update x/bank * Update x/bank events docs * Update x/crisis module events * Reset context with events on each message exec * Update x/distribution events and docs * Update BaseApp to not set empty events manually * Implement simple event manager * Update module manager * Update modules to use event manager * Update x/gov module to use events * Update events docs * Update gov queries and crisis app module * Update bank keeper * Add events to minting begin blocker * Update modules to use types/events.go * Cleanup x/mint * Update x/staking events * Update x/staking events * Update events to have sender part of message.sender * Fix build * Fix module unit tests * Add pending log entry * Update deps * Update x/crisis/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/bank/internal/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/distribution/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/mint/internal/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/slashing/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/gov/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/gov/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/mint/abci.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/mint/abci.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/slashing/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/slashing/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Upgrade TM to v0.32.0-dev1 * Update events as strings * Update Tendermint to v0.32.0-dev2 * Fix BaseApp unit tests * Fix unit tests * Bump tendermint version to v0.32.0 * typos
2019-06-26 09:03:25 -07:00
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeSlash,
sdk.NewAttribute(types.AttributeKeyAddress, consAddr.String()),
sdk.NewAttribute(types.AttributeKeyPower, fmt.Sprintf("%d", power)),
sdk.NewAttribute(types.AttributeKeyReason, types.AttributeValueMissingSignature),
sdk.NewAttribute(types.AttributeKeyJailed, consAddr.String()),
),
)
k.sk.Slash(ctx, consAddr, distributionHeight, power, k.SlashFractionDowntime(ctx))
k.sk.Jail(ctx, consAddr)
Merge PR #4541: Events Tracking / Tendermint v0.32.0 Update * Update Tendermint to v0.32.0-dev0 * Initial refactor of tags * Update event types and add unit tests * Refactor context * Update module manager * Update result godoc * Implement ToABCIEvents * Update BaseApp * Minor cleanup * Fix typo * Update x/bank message handler * Update x/bank keeper * Update x/bank * Update x/bank events docs * Update x/crisis module events * Reset context with events on each message exec * Update x/distribution events and docs * Update BaseApp to not set empty events manually * Implement simple event manager * Update module manager * Update modules to use event manager * Update x/gov module to use events * Update events docs * Update gov queries and crisis app module * Update bank keeper * Add events to minting begin blocker * Update modules to use types/events.go * Cleanup x/mint * Update x/staking events * Update x/staking events * Update events to have sender part of message.sender * Fix build * Fix module unit tests * Add pending log entry * Update deps * Update x/crisis/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/bank/internal/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/distribution/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/mint/internal/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/slashing/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/types/events.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/gov/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/gov/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/mint/abci.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/mint/abci.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/slashing/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/slashing/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Update x/staking/handler.go Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> * Upgrade TM to v0.32.0-dev1 * Update events as strings * Update Tendermint to v0.32.0-dev2 * Fix BaseApp unit tests * Fix unit tests * Bump tendermint version to v0.32.0 * typos
2019-06-26 09:03:25 -07:00
2019-01-10 17:22:49 -08:00
signInfo.JailedUntil = ctx.BlockHeader().Time.Add(k.DowntimeJailDuration(ctx))
2018-10-15 12:44:23 -07:00
// We need to reset the counter & array so that the validator won't be immediately slashed for downtime upon rebonding.
signInfo.MissedBlocksCounter = 0
signInfo.IndexOffset = 0
k.clearValidatorMissedBlockBitArray(ctx, consAddr)
logger.Info(
"slashing and jailing validator due to liveness fault",
"height", height,
"validator", consAddr.String(),
"min_height", minHeight,
"threshold", minSignedPerWindow,
"slashed", k.SlashFractionDowntime(ctx).String(),
"jailed_until", signInfo.JailedUntil,
)
} else {
// validator was (a) not found or (b) already jailed so we do not slash
logger.Info(
"validator would have been slashed for downtime, but was either not found in store or already jailed",
"validator", consAddr.String(),
)
}
2018-05-23 13:25:56 -07:00
}
2018-05-28 17:35:42 -07:00
// Set the updated signing info
k.SetValidatorSigningInfo(ctx, consAddr, signInfo)
2018-05-23 13:25:56 -07:00
}