Skip to content

Commit

Permalink
fix: non determinism in lottery ranking fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
ze97286 committed Aug 8, 2024
1 parent 4205bf7 commit 69a7b7d
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
- [11521](https://github.com/vegaprotocol/vega/issues/11521) - Restore `AMM` position factor when loading from a snapshot.
- [11526](https://github.com/vegaprotocol/vega/issues/11526) - `EstimateAMMBounds` now respects the market's decimal places.
- [11540](https://github.com/vegaprotocol/vega/issues/11540) - Fix spam check for spots to use not double count quantum.
- [11542](https://github.com/vegaprotocol/vega/issues/11542) - Fix non determinism in lottery ranking.

## 0.77.5

Expand Down
34 changes: 24 additions & 10 deletions core/rewards/lottery_ranking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,35 @@ import (

"code.vegaprotocol.io/vega/core/types"
"code.vegaprotocol.io/vega/libs/num"
"golang.org/x/exp/rand"

Check failure on line 24 in core/rewards/lottery_ranking_test.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with --skip-generated -s standard -s prefix(code.vegaprotocol.io/vega) -s default -s blank -s dot --custom-order (gci)

"github.com/stretchr/testify/require"

Check failure on line 26 in core/rewards/lottery_ranking_test.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gci`-ed with --skip-generated -s standard -s prefix(code.vegaprotocol.io/vega) -s default -s blank -s dot --custom-order (gci)
)

func TestLotteryRewardScoreSorting(t *testing.T) {
adjustedRewardScores := []*types.PartyContributionScore{
{Party: "p1", Score: num.DecimalOne()},
{Party: "p2", Score: num.DecimalTwo()},
{Party: "p3", Score: num.DecimalFromFloat(0.01)},
for i := 0; i < 100; i++ {
adjustedRewardScores := []*types.PartyContributionScore{
{Party: "p1", Score: num.DecimalOne()},
{Party: "p2", Score: num.DecimalTwo()},
{Party: "p3", Score: num.DecimalFromFloat(0.01)},
}
const layout = "Jan 2, 2006 at 3:04pm"

timestamp, _ := time.Parse(layout, "Aug 7, 2024 at 12:00pm")
lottery := lotteryRewardScoreSorting(adjustedRewardScores, timestamp)
require.Equal(t, "p2", lottery[0].Party)
require.Equal(t, "p1", lottery[1].Party)
require.Equal(t, "p3", lottery[2].Party)
}
const layout = "Jan 2, 2006 at 3:04pm"
}

timestamp, _ := time.Parse(layout, "Aug 7, 2024 at 12:00pm")
lottery := lotteryRewardScoreSorting(adjustedRewardScores, timestamp)
require.Equal(t, "p2", lottery[0].Party)
require.Equal(t, "p1", lottery[1].Party)
require.Equal(t, "p3", lottery[2].Party)
func TestRandom(t *testing.T) {
for i := 0; i < 1000; i++ {
const layout = "Jan 2, 2006 at 3:04pm"
timestamp, _ := time.Parse(layout, "Aug 7, 2024 at 12:00pm")
source := rand.NewSource(uint64(timestamp.UnixNano()))
rng := rand.New(source)
next := rng.Int63n(100)
require.Equal(t, int64(27), next)
}
}
29 changes: 25 additions & 4 deletions core/rewards/reward_distribution.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ func selectIndex(rng *rand.Rand, probabilities []num.Decimal) int {
return len(probabilities) - 1
}

type PartyProbability struct {
Probability num.Decimal
Party string
}

func lotteryRewardScoreSorting(adjustedPartyScores []*types.PartyContributionScore, timestamp time.Time) []*types.PartyContributionScore {
source := rand.NewSource(uint64(timestamp.UnixNano()))
rng := rand.New(source)
Expand All @@ -148,12 +153,28 @@ func lotteryRewardScoreSorting(adjustedPartyScores []*types.PartyContributionSco
if len(unselectedParties) < 1 {
break
}
probabilities := make([]num.Decimal, 0, len(unselectedParties))
parties := make([]string, 0, len(unselectedParties))
pp := make([]PartyProbability, 0, len(unselectedParties))
for _, ps := range unselectedParties {
probabilities = append(probabilities, ps.Score.Div(totalScores))
parties = append(parties, ps.Party)
pp = append(pp, PartyProbability{
Probability: ps.Score.Div(totalScores),
Party: ps.Party,
})
}
sort.Slice(pp, func(i, j int) bool {
if pp[i].Probability.Equal(pp[j].Probability) {
return pp[i].Party < pp[j].Party
}
return pp[i].Probability.LessThan(pp[j].Probability)
})

probabilities := make([]num.Decimal, len(pp))
parties := make([]string, len(pp))

for i, partyProb := range pp {
probabilities[i] = partyProb.Probability
parties[i] = partyProb.Party
}

selected := selectIndex(rng, probabilities)
selectedParty := unselectedParties[parties[selected]]
delete(unselectedParties, selectedParty.Party)
Expand Down

0 comments on commit 69a7b7d

Please sign in to comment.