Skip to content

Commit

Permalink
tombstoned
Browse files Browse the repository at this point in the history
  • Loading branch information
sunnya97 committed Jan 6, 2019
1 parent 5bc49ff commit 2b8c670
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 12 deletions.
4 changes: 4 additions & 0 deletions x/slashing/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ func handleMsgUnjail(ctx sdk.Context, msg MsgUnjail, k Keeper) sdk.Result {
return ErrNoValidatorForAddress(k.codespace).Result()
}

if info.Tombstoned {
return ErrValidatorJailed(k.codespace).Result()
}

// cannot be unjailed until out of jail
if ctx.BlockHeader().Time.Before(info.JailedUntil) {
return ErrValidatorJailed(k.codespace).Result()
Expand Down
28 changes: 19 additions & 9 deletions x/slashing/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio
panic(fmt.Sprintf("Validator consensus-address %v not found", consAddr))
}

// Double sign too old
maxEvidenceAge := k.MaxEvidenceAge(ctx)
if age > maxEvidenceAge {
logger.Info(fmt.Sprintf("Ignored double sign from %s at height %d, age of %d past max age of %d", pubkey.Address(), infractionHeight, age, maxEvidenceAge))
return
}

// Get validator.
validator := k.validatorSet.ValidatorByConsAddr(ctx, consAddr)
if validator == nil || validator.GetStatus() == sdk.Unbonded {
Expand All @@ -55,11 +62,14 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio
// Tendermint might break this assumption at some point.
return
}
signInfo, found := k.getValidatorSigningInfo(ctx, consAddr)
if !found {
panic(fmt.Sprintf("Expected signing info for validator %s but not found", consAddr))
}

// Double sign too old
maxEvidenceAge := k.MaxEvidenceAge(ctx)
if age > maxEvidenceAge {
logger.Info(fmt.Sprintf("Ignored double sign from %s at height %d, age of %d past max age of %d", pubkey.Address(), infractionHeight, age, maxEvidenceAge))
// Validator is already tombstoned
if signInfo.Tombstoned {
logger.Info(fmt.Sprintf("Ignored double sign from %s at height %d, validator already tombstoned", pubkey.Address(), infractionHeight))
return
}

Expand Down Expand Up @@ -89,13 +99,13 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio
k.validatorSet.Jail(ctx, consAddr)
}

// Set or updated validator jail duration
signInfo, found := k.getValidatorSigningInfo(ctx, consAddr)
if !found {
panic(fmt.Sprintf("Expected signing info for validator %s but not found", consAddr))
}
// Set slashed so far to total slash
signInfo.Tombstoned = true

// Set jailed until to be forever (max time)
signInfo.JailedUntil = DoubleSignJailEndTime

// Set validator signing info
k.SetValidatorSigningInfo(ctx, consAddr, signInfo)
}

Expand Down
11 changes: 9 additions & 2 deletions x/slashing/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,14 @@ func TestHandleDoubleSign(t *testing.T) {
require.True(t, sk.Validator(ctx, operatorAddr).GetJailed())

// tokens should be decreased
require.True(t, sk.Validator(ctx, operatorAddr).GetTokens().LT(oldTokens))
newTokens := sk.Validator(ctx, operatorAddr).GetTokens()
require.True(t, newTokens.LT(oldTokens))

// New evidence
keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt)

// tokens should be the same (capped slash)
require.True(t, sk.Validator(ctx, operatorAddr).GetTokens().Equal(newTokens))

// Jump to past the unbonding period
ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(sk.GetParams(ctx).UnbondingTime)})
Expand Down Expand Up @@ -220,7 +227,7 @@ func TestHandleAbsentValidator(t *testing.T) {
pool = sk.GetPool(ctx)
require.Equal(t, amtInt64-slashAmt, pool.BondedTokens.Int64())

// validator start height should not have been changed
// Validator start height should not have been changed
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
require.True(t, found)
require.Equal(t, int64(0), info.StartHeight)
Expand Down
4 changes: 3 additions & 1 deletion x/slashing/signing_info.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,12 @@ func (k Keeper) clearValidatorMissedBlockBitArray(ctx sdk.Context, address sdk.C
}

// Construct a new `ValidatorSigningInfo` struct
func NewValidatorSigningInfo(startHeight int64, indexOffset int64, jailedUntil time.Time, missedBlocksCounter int64) ValidatorSigningInfo {
func NewValidatorSigningInfo(startHeight int64, indexOffset int64, jailedUntil time.Time, tombstoned bool, missedBlocksCounter int64) ValidatorSigningInfo {
return ValidatorSigningInfo{
StartHeight: startHeight,
IndexOffset: indexOffset,
JailedUntil: jailedUntil,
Tombstoned: tombstoned,
MissedBlocksCounter: missedBlocksCounter,
}
}
Expand All @@ -105,6 +106,7 @@ type ValidatorSigningInfo struct {
StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unjailed
IndexOffset int64 `json:"index_offset"` // index offset into signed block bit array
JailedUntil time.Time `json:"jailed_until"` // timestamp validator cannot be unjailed until
Tombstoned bool `json:"tombstone"` // whether or not a validator has been tombstoned (killed out of validator set)
MissedBlocksCounter int64 `json:"missed_blocks_counter"` // missed blocks counter (to avoid scanning the array every time)
}

Expand Down

0 comments on commit 2b8c670

Please sign in to comment.