From 20f826df7ff9305cba7d97f5145e8e21c130b1af Mon Sep 17 00:00:00 2001 From: Martin Dyring-Andersen Date: Tue, 20 Oct 2020 14:14:56 +0200 Subject: [PATCH] Only slash after signedBlocksWindow has passed Closes #19 --- x/slashing/abci.go | 23 ++++++++++++----------- x/slashing/keeper.go | 9 +++++++-- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/x/slashing/abci.go b/x/slashing/abci.go index 367f2fb0..8891c360 100644 --- a/x/slashing/abci.go +++ b/x/slashing/abci.go @@ -24,7 +24,7 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper, batch blockTimes := sk.getBlockTimes() blockTimes = append(blockTimes, ctx.BlockTime()) - blockTimes = truncateByWindow(ctx.BlockTime(), blockTimes, signedBlocksWindow) + _, blockTimes = truncateByWindow(ctx.BlockTime(), blockTimes, signedBlocksWindow) sk.setBlockTimes(batch, blockTimes) sk.handlePendingPenalties(ctx, batch, validatorset(req.LastCommitInfo.Votes)) @@ -61,17 +61,18 @@ func validatorset(validators []abci.VoteInfo) func() map[string]bool { } } -func truncateByWindow(blockTime time.Time, times []time.Time, signedBlocksWindow time.Duration) []time.Time { - if len(times) == 0 { - return times - } +func truncateByWindow(blockTime time.Time, times []time.Time, signedBlocksWindow time.Duration) (bool, []time.Time) { + + if len(times) > 0 && times[0].Add(signedBlocksWindow).Before(blockTime) { + // Remove timestamps outside of the time window we are watching + threshold := blockTime.Add(-signedBlocksWindow) - // Remove timestamps outside of the time window we are watching - threshold := blockTime.Add(-1 * signedBlocksWindow) + index := sort.Search(len(times), func(i int) bool { + return times[i].After(threshold) + }) - index := sort.Search(len(times), func(i int) bool { - return times[i].After(threshold) - }) + return true, times[index:] + } - return times[index:] + return false, times } diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index aabd3e44..f200370f 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -167,15 +167,20 @@ func (k Keeper) HandleValidatorSignature(ctx sdk.Context, batch db.Batch, addr c consAddr := sdk.ConsAddress(addr) missedBlocks := k.getMissingBlocksForValidator(consAddr) - missedBlocks = truncateByWindow(ctx.BlockTime(), missedBlocks, k.SignedBlocksWindowDuration(ctx)) + truncated, missedBlocks := truncateByWindow(ctx.BlockTime(), missedBlocks, k.SignedBlocksWindowDuration(ctx)) if !signed { missedBlocks = append(missedBlocks, ctx.BlockTime()) } k.setMissingBlocksForValidator(batch, consAddr, missedBlocks) - missedBlockCount := sdk.NewInt(int64(len(missedBlocks))).ToDec() + // Validator is only slashable if the signed block window is full (was truncated) + if !truncated { + return + } + + missedBlockCount := sdk.NewInt(int64(len(missedBlocks))).ToDec() missedRatio := missedBlockCount.QuoInt64(blockCount) // TODO Only do this if missing is true?