-
Notifications
You must be signed in to change notification settings - Fork 211
/
votes_calc.go
65 lines (54 loc) · 1.64 KB
/
votes_calc.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
package beacon
import (
"encoding/hex"
"math/big"
"go.uber.org/zap/zapcore"
"github.com/spacemeshos/go-spacemesh/log"
)
func calcVotes(logger log.Log, theta *big.Float, s *state) (allVotes, proposalList) {
logger.With().Debug("calculating votes", log.Object("vote_margins", zapcore.ObjectMarshalerFunc(
func(enc zapcore.ObjectEncoder) error {
for vote, margin := range s.votesMargin {
enc.AddString(hex.EncodeToString(vote[:]), margin.String())
}
return nil
})))
ownCurrentRoundVotes := allVotes{
support: make(proposalSet),
against: make(proposalSet),
}
positiveVotingThreshold := votingThreshold(theta, s.epochWeight)
negativeThreshold := new(big.Int).Neg(positiveVotingThreshold)
var undecided proposalList
for vote, weightCount := range s.votesMargin {
switch {
case weightCount.Cmp(positiveVotingThreshold) >= 0:
ownCurrentRoundVotes.support[vote] = struct{}{}
case weightCount.Cmp(negativeThreshold) <= 0:
ownCurrentRoundVotes.against[vote] = struct{}{}
default:
undecided = append(undecided, vote)
}
}
logger.With().Debug("calculated votes for one round",
log.Array("for_votes", ownCurrentRoundVotes.support),
log.Array("against_votes", ownCurrentRoundVotes.against),
)
return ownCurrentRoundVotes, undecided
}
func votingThreshold(theta *big.Float, epochWeight uint64) *big.Int {
v, _ := new(big.Float).Mul(
theta,
new(big.Float).SetUint64(epochWeight),
).Int(nil)
return v
}
func tallyUndecided(votes *allVotes, undecided proposalList, coinFlip bool) {
for _, vote := range undecided {
if coinFlip {
votes.support[vote] = struct{}{}
} else {
votes.against[vote] = struct{}{}
}
}
}