-
Notifications
You must be signed in to change notification settings - Fork 175
/
round.go
89 lines (73 loc) · 2.17 KB
/
round.go
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
// (c) 2019 Dapper Labs - ALL RIGHTS RESERVED
package round
import (
"github.com/onflow/flow-go/model/flow"
"github.com/onflow/flow-go/model/flow/filter"
"github.com/onflow/flow-go/module"
)
// Round keeps track of the current consensus state.
type Round struct {
parent *flow.Header
leader *flow.Identity
quorum uint64
participants flow.IdentityList
candidate *flow.Header
votes map[flow.Identifier]uint64
}
// New creates a new consensus round.
func New(head *flow.Header, me module.Local, participants flow.IdentityList) (*Round, error) {
// pick the leader on a fixed round-robin basis
leader := participants[int(head.Height)%len(participants)]
// remove ourselves from the participants
quorum := participants.TotalStake()
participants = participants.Filter(filter.Not(filter.HasNodeID(me.NodeID())))
s := &Round{
parent: head,
leader: leader,
quorum: quorum,
participants: participants,
votes: make(map[flow.Identifier]uint64),
}
return s, nil
}
// Parent returns the parent of the to-be-formed block.
func (r *Round) Parent() *flow.Header {
return r.parent
}
// Participants will retrieve cached identities for this round.
func (r *Round) Participants() flow.IdentityList {
return r.participants
}
// Quorum returns the quorum for a qualified majority in this round.
func (r *Round) Quorum() uint64 {
return r.quorum
}
// Leader returns the the leader of the current round.
func (r *Round) Leader() *flow.Identity {
return r.leader
}
// Propose sets the current candidate header.
func (r *Round) Propose(candidate *flow.Header) {
r.candidate = candidate
}
// Candidate returns the current candidate header.
func (r *Round) Candidate() *flow.Header {
return r.candidate
}
// Voted checks if the given node has already voted.
func (r *Round) Voted(nodeID flow.Identifier) bool {
_, ok := r.votes[nodeID]
return ok
}
// Tally will add the given vote to the node tally.
func (r *Round) Tally(voterID flow.Identifier, stake uint64) {
r.votes[voterID] = stake
}
// Votes will count the total votes.
func (r *Round) Votes() uint64 {
var votes uint64
for _, stake := range r.votes {
votes += stake
}
return votes
}