aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/tangerine-network/tangerine-consensus/core/utils/vote-filter.go
blob: 0a7731138657e6de5aff02f76b92051226e1c2ff (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
// Copyright 2019 The dexon-consensus Authors
// This file is part of the dexon-consensus library.
//
// The dexon-consensus library is free software: you can redistribute it
// and/or modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// The dexon-consensus library is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
// General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the dexon-consensus library. If not, see
// <http://www.gnu.org/licenses/>.

package utils

import (
    "github.com/tangerine-network/tangerine-consensus/core/types"
)

// VoteFilter filters votes that are useless for now.
// To maximize performance, this structure is not thread-safe and will never be.
type VoteFilter struct {
    Voted    map[types.VoteHeader]struct{}
    Position types.Position
    LockIter uint64
    Period   uint64
    Confirm  bool
}

// NewVoteFilter creates a new vote filter instance.
func NewVoteFilter() *VoteFilter {
    return &VoteFilter{
        Voted: make(map[types.VoteHeader]struct{}),
    }
}

// Filter checks if the vote should be filtered out.
func (vf *VoteFilter) Filter(vote *types.Vote) bool {
    if vote.Type == types.VoteInit {
        return true
    }
    if vote.Position.Older(vf.Position) {
        return true
    } else if vote.Position.Newer(vf.Position) {
        // It's impossible to check the vote of other height.
        return false
    }
    if vf.Confirm {
        return true
    }
    if vote.Type == types.VotePreCom && vote.Period < vf.LockIter {
        return true
    }
    if vote.Type == types.VoteCom &&
        vote.Period < vf.Period &&
        vote.BlockHash == types.SkipBlockHash {
        return true
    }
    if _, exist := vf.Voted[vote.VoteHeader]; exist {
        return true
    }
    return false
}

// AddVote to the filter so the same vote will be filtered.
func (vf *VoteFilter) AddVote(vote *types.Vote) {
    vf.Voted[vote.VoteHeader] = struct{}{}
}