Skip to content

Commit

Permalink
sort cross rate ballot and enforce sorted before computing weighted m…
Browse files Browse the repository at this point in the history
…edian
  • Loading branch information
yun-yeo committed Dec 10, 2021
1 parent d411ae7 commit b073fb1
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 3 deletions.
35 changes: 32 additions & 3 deletions x/oracle/abci_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing"

"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/rand"

sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
Expand Down Expand Up @@ -335,14 +336,14 @@ func TestOracleExchangeRate(t *testing.T) {
input, h := setup(t)

krwRandomExchangeRate := sdk.NewDecWithPrec(1000000000, int64(6)).MulInt64(core.MicroUnit)
uswRandomExchangeRate := sdk.NewDecWithPrec(1000000, int64(6)).MulInt64(core.MicroUnit)
usdRandomExchangeRate := sdk.NewDecWithPrec(1000000, int64(6)).MulInt64(core.MicroUnit)

// KRW has been chosen as referenceTerra by highest voting power
// Account 1, USD, KRW
makeAggregatePrevoteAndVote(t, input, h, 0, sdk.DecCoins{{Denom: core.MicroUSDDenom, Amount: uswRandomExchangeRate}, {Denom: core.MicroKRWDenom, Amount: krwRandomExchangeRate}}, 0)
makeAggregatePrevoteAndVote(t, input, h, 0, sdk.DecCoins{{Denom: core.MicroUSDDenom, Amount: usdRandomExchangeRate}, {Denom: core.MicroKRWDenom, Amount: krwRandomExchangeRate}}, 0)

// Account 2, USD, KRW
makeAggregatePrevoteAndVote(t, input, h, 0, sdk.DecCoins{{Denom: core.MicroUSDDenom, Amount: uswRandomExchangeRate}, {Denom: core.MicroKRWDenom, Amount: krwRandomExchangeRate}}, 1)
makeAggregatePrevoteAndVote(t, input, h, 0, sdk.DecCoins{{Denom: core.MicroUSDDenom, Amount: usdRandomExchangeRate}, {Denom: core.MicroKRWDenom, Amount: krwRandomExchangeRate}}, 1)

// Account 3, KRW, SDR
makeAggregatePrevoteAndVote(t, input, h, 0, sdk.DecCoins{{Denom: core.MicroKRWDenom, Amount: krwRandomExchangeRate}, {Denom: core.MicroSDRDenom, Amount: randomExchangeRate}}, 2)
Expand All @@ -364,6 +365,34 @@ func TestOracleExchangeRate(t *testing.T) {
require.Equal(t, expectedRewardAmt2, rewards.Rewards.AmountOf(core.MicroLunaDenom).TruncateInt())
}

func TestOracleEnsureSorted(t *testing.T) {
input, h := setup(t)

for i := 0; i < 100; i++ {
krwExchangeRate1 := sdk.NewDecWithPrec(int64(rand.Uint64()%100000000), 6).MulInt64(core.MicroUnit)
usdExchangeRate1 := sdk.NewDecWithPrec(int64(rand.Uint64()%100000000), 6).MulInt64(core.MicroUnit)

krwExchangeRate2 := sdk.NewDecWithPrec(int64(rand.Uint64()%100000000), 6).MulInt64(core.MicroUnit)
usdExchangeRate2 := sdk.NewDecWithPrec(int64(rand.Uint64()%100000000), 6).MulInt64(core.MicroUnit)

krwExchangeRate3 := sdk.NewDecWithPrec(int64(rand.Uint64()%100000000), 6).MulInt64(core.MicroUnit)
usdExchangeRate3 := sdk.NewDecWithPrec(int64(rand.Uint64()%100000000), 6).MulInt64(core.MicroUnit)

// Account 1, USD, KRW
makeAggregatePrevoteAndVote(t, input, h, 0, sdk.DecCoins{{Denom: core.MicroUSDDenom, Amount: usdExchangeRate1}, {Denom: core.MicroKRWDenom, Amount: krwExchangeRate1}}, 0)

// Account 2, USD, KRW
makeAggregatePrevoteAndVote(t, input, h, 0, sdk.DecCoins{{Denom: core.MicroUSDDenom, Amount: usdExchangeRate2}, {Denom: core.MicroKRWDenom, Amount: krwExchangeRate2}}, 1)

// Account 3, USD, KRW
makeAggregatePrevoteAndVote(t, input, h, 0, sdk.DecCoins{{Denom: core.MicroUSDDenom, Amount: krwExchangeRate3}, {Denom: core.MicroKRWDenom, Amount: usdExchangeRate3}}, 2)

require.NotPanics(t, func() {
oracle.EndBlocker(input.Ctx.WithBlockHeight(1), input.OracleKeeper)
})
}
}

func TestOracleExchangeRateVal5(t *testing.T) {
input, h := setupVal5(t)

Expand Down
6 changes: 6 additions & 0 deletions x/oracle/types/ballot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package types
import (
"fmt"
"math"
"sort"
"strconv"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -60,6 +61,7 @@ func (pb ExchangeRateBallot) ToCrossRate(bases map[string]sdk.Dec) (cb ExchangeR
cb = append(cb, vote)
}

sort.Sort(cb)
return
}

Expand All @@ -76,6 +78,10 @@ func (pb ExchangeRateBallot) Power() int64 {
// WeightedMedian returns the median weighted by the power of the ExchangeRateVote.
// CONTRACT: ballot must be sorted
func (pb ExchangeRateBallot) WeightedMedian() sdk.Dec {
if !sort.IsSorted(pb) {
panic("ballot must be sorted")
}

totalPower := pb.Power()
if pb.Len() > 0 {
pivot := int64(0)
Expand Down
3 changes: 3 additions & 0 deletions x/oracle/types/ballot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package types
import (
"fmt"
"math"
"sort"
"strconv"

"testing"
Expand Down Expand Up @@ -103,6 +104,8 @@ func TestToCrossRate(t *testing.T) {
}
}

sort.Sort(cb)

baseMapBallot := pbBase.ToMap()
require.Equal(t, cb, pbQuote.ToCrossRate(baseMapBallot))
}
Expand Down

0 comments on commit b073fb1

Please sign in to comment.