Skip to content

Commit

Permalink
Merge pull request #108 from line/fix/votingpower_panic
Browse files Browse the repository at this point in the history
fix minus voting power panic
  • Loading branch information
Woosang Son authored Jul 20, 2020
2 parents 171bbf9 + 9f38532 commit e2aa138
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
18 changes: 12 additions & 6 deletions libs/rand/sampling.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,20 @@ func RandomSamplingWithoutReplacement(
compensationProportions[i].Add(&compensationProportions[i+1], additionalCompensation)
}
winners = candidates[len(candidates)-winnerNum:]
winPoints := make([]*big.Int, len(winners))
totalWinPoint := new(big.Int)
for i, winner := range winners {
winPoints[i] = new(big.Int).SetUint64(winner.Priority())
winPoints[i].Mul(winPoints[i], &compensationProportions[i])
winPoints[i].Add(winPoints[i], correction)
totalWinPoint.Add(totalWinPoint, winPoints[i])
}
recalibration := new(big.Int).Div(correction, new(big.Int).SetUint64(precisionCorrectionForSelection))
for i, winner := range winners {
// winPoint = correction + winner.Priority() * compensationProportions[i]
winPoint := new(big.Int).SetUint64(winner.Priority())
winPoint.Mul(winPoint, &compensationProportions[i])
winPoint.Add(winPoint, correction)

winner.SetWinPoint(winPoint.Div(winPoint, recalibration).Int64())
winPoint := new(big.Int)
winPoint.Mul(recalibration, winPoints[i])
winPoint.Div(winPoint, totalWinPoint)
winner.SetWinPoint(winPoint.Int64())
}
return winners
}
Expand Down
1 change: 0 additions & 1 deletion libs/rand/sampling_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ func TestRandomSamplingWithoutReplacementOverflow(t *testing.T) {
assert.True(t, element.winPoint <= lastWinPoint)
lastWinPoint = element.winPoint
}
assert.Equal(t, lastWinPoint, int64(precisionForSelection))
}

func accumulateAndResetReward(candidate []Candidate, acc []uint64) uint64 {
Expand Down
45 changes: 45 additions & 0 deletions types/voter_set_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"math"
"testing"

"github.com/tendermint/tendermint/libs/rand"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -393,3 +395,46 @@ func TestVoterSetProtoBuf(t *testing.T) {
}
}
}

func testVotingPower(t *testing.T, valSet *ValidatorSet) {
voterParams := &VoterParams{
VoterElectionThreshold: 100,
MaxTolerableByzantinePercentage: 20,
ElectionPrecision: 2,
}

voterSetNoSampling := SelectVoter(valSet, []byte{0}, voterParams)
for _, v := range voterSetNoSampling.Voters {
assert.True(t, v.StakingPower == v.VotingPower)
}

for i := 90; i > 50; i-- {
voterParams.VoterElectionThreshold = int32(i)
voterSetSampling := SelectVoter(valSet, []byte{0}, voterParams)
allSame := true
for _, v := range voterSetSampling.Voters {
if v.StakingPower != v.VotingPower {
allSame = false
break
}
}
assert.False(t, allSame)
assert.True(t, valSet.TotalStakingPower() > voterSetSampling.TotalVotingPower())
// total voting power can not be less than total staking power - precisionForSelection(1000)
assert.True(t, valSet.TotalStakingPower()-voterSetSampling.TotalVotingPower() <= 1000)
}
}

func TestVotingPower(t *testing.T) {
testVotingPower(t, randValidatorSet(100))
vals := make([]*Validator, 100)
for i := 0; i < len(vals); i++ {
vals[i] = newValidator(rand.Bytes(32), 100)
}
testVotingPower(t, NewValidatorSet(vals))
vals2 := make([]*Validator, 100)
for i := 0; i < len(vals2); i++ {
vals2[i] = newValidator(rand.Bytes(32), MaxTotalStakingPower/100)
}
testVotingPower(t, NewValidatorSet(vals2))
}

0 comments on commit e2aa138

Please sign in to comment.