Skip to content

Commit

Permalink
refactor: Update historic medians query (#1651)
Browse files Browse the repository at this point in the history
* Add median stats grpc queries

* Fix query methods

* Remove uneeded queries

* Update x/oracle/keeper/grpc_query.go

Co-authored-by: Adam Wozniak <29418299+adamewozniak@users.noreply.github.com>

* Bound numStamps param in medians query

* field reorder + make proto-all

* Update proto/umee/oracle/v1/query.proto

Co-authored-by: Robert Zaremba <robert@zaremba.ch>

* PR comments

* lint

Co-authored-by: Adam Wozniak <29418299+adamewozniak@users.noreply.github.com>
Co-authored-by: toteki <63419657+toteki@users.noreply.github.com>
Co-authored-by: Robert Zaremba <robert@zaremba.ch>
  • Loading branch information
4 people committed Dec 15, 2022
1 parent 2782a97 commit 58a49b6
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 98 deletions.
3 changes: 3 additions & 0 deletions proto/umee/oracle/v1/query.proto
Expand Up @@ -252,6 +252,9 @@ message QueryMedians {
option (gogoproto.goproto_getters) = false;
// denom defines the denomination to query for.
string denom = 1;
// numStamps defines the number of median stamps to query for. numStamps
// must be greater than 0.
uint32 numStamps = 2;
}

// QueryMediansResponse is response type for the
Expand Down
10 changes: 10 additions & 0 deletions swagger/swagger.yaml
Expand Up @@ -1073,6 +1073,16 @@ paths:
in: query
required: false
type: string
- name: numStamps
description: >-
numStamps defines the number of median stamps to query for.
numStamps
must be greater than 0.
in: query
required: false
type: integer
format: int64
tags:
- Query
/umee/oracle/v1/denoms/active_exchange_rates:
Expand Down
24 changes: 12 additions & 12 deletions x/oracle/abci_test.go
Expand Up @@ -16,8 +16,8 @@ import (

umeeapp "github.com/umee-network/umee/v3/app"
appparams "github.com/umee-network/umee/v3/app/params"
"github.com/umee-network/umee/v3/x/oracle/keeper"
"github.com/umee-network/umee/v3/x/oracle"
"github.com/umee-network/umee/v3/x/oracle/keeper"
"github.com/umee-network/umee/v3/x/oracle/types"
)

Expand All @@ -42,11 +42,11 @@ func clearHistoricPrices(
ctx sdk.Context,
k keeper.Keeper,
denom string,
) {
stampPeriod := int(k.HistoricStampPeriod(ctx))
) {
stampPeriod := int(k.HistoricStampPeriod(ctx))
numStamps := int(k.MaximumPriceStamps(ctx))
for i := 0; i < numStamps; i++ {
k.DeleteHistoricPrice(ctx, denom, uint64(ctx.BlockHeight()) - uint64(i*stampPeriod))
for i := 0; i < numStamps; i++ {
k.DeleteHistoricPrice(ctx, denom, uint64(ctx.BlockHeight())-uint64(i*stampPeriod))
}
}

Expand All @@ -55,11 +55,11 @@ func clearHistoricMedians(
ctx sdk.Context,
k keeper.Keeper,
denom string,
) {
stampPeriod := int(k.MedianStampPeriod(ctx))
) {
stampPeriod := int(k.MedianStampPeriod(ctx))
numStamps := int(k.MaximumMedianStamps(ctx))
for i := 0; i < numStamps; i++ {
k.DeleteHistoricMedian(ctx, denom, uint64(ctx.BlockHeight()) - uint64(i*stampPeriod))
k.DeleteHistoricMedian(ctx, denom, uint64(ctx.BlockHeight())-uint64(i*stampPeriod))
}
}

Expand All @@ -69,11 +69,11 @@ func clearHistoricMedianDeviations(
ctx sdk.Context,
k keeper.Keeper,
denom string,
) {
stampPeriod := int(k.MedianStampPeriod(ctx))
) {
stampPeriod := int(k.MedianStampPeriod(ctx))
numStamps := int(k.MaximumMedianStamps(ctx))
for i := 0; i < numStamps; i++ {
k.DeleteHistoricMedianDeviation(ctx, denom, uint64(ctx.BlockHeight()) - uint64(i*stampPeriod))
for i := 0; i < numStamps; i++ {
k.DeleteHistoricMedianDeviation(ctx, denom, uint64(ctx.BlockHeight())-uint64(i*stampPeriod))
}
}

Expand Down
24 changes: 17 additions & 7 deletions x/oracle/keeper/grpc_query.go
Expand Up @@ -262,19 +262,29 @@ func (q querier) Medians(

ctx := sdk.UnwrapSDKContext(goCtx)

var medians sdk.DecCoins
medians := make([]sdk.DecCoin, 0)

if len(req.Denom) > 0 {
// TODO: Add numStamps param to request to enable responding with a variable amount
// of last medians rather than just returning the most recent stamp
medianList := q.HistoricMedians(ctx, req.Denom, 1)
if req.NumStamps == 0 {
return nil, status.Error(codes.InvalidArgument, "parameter NumStamps must be greater than 0")
}

if req.NumStamps > uint32(q.MaximumMedianStamps(ctx)) {
req.NumStamps = uint32(q.MaximumMedianStamps(ctx))
}

medians = make(sdk.DecCoins, req.NumStamps)
medianList := q.HistoricMedians(ctx, req.Denom, uint64(req.NumStamps))

if len(medianList) != 0 {
medians = medians.Add(sdk.NewDecCoinFromDec(req.Denom, medianList[0]))
for i, median := range medianList {
medians[i] = sdk.NewDecCoinFromDec(req.Denom, median)
}
} else {
q.IterateAllMedianPrices(ctx, func(median types.Price) (stop bool) {
medians = medians.Add(sdk.NewDecCoinFromDec(median.ExchangeRateTuple.Denom, median.ExchangeRateTuple.ExchangeRate))
medians = append(
medians,
sdk.NewDecCoinFromDec(median.ExchangeRateTuple.Denom, median.ExchangeRateTuple.ExchangeRate),
)
return false
})
}
Expand Down
32 changes: 24 additions & 8 deletions x/oracle/keeper/grpc_query_test.go
Expand Up @@ -205,20 +205,36 @@ func (s *IntegrationTestSuite) TestQuerier_AggregateVotesAppendVotes() {
func (s *IntegrationTestSuite) TestQuerier_Medians() {
app, ctx := s.app, s.ctx

atomMedian := sdk.DecCoin{Denom: "atom", Amount: sdk.MustNewDecFromStr("49.99")}
umeeMedian := sdk.DecCoin{Denom: "umee", Amount: sdk.MustNewDecFromStr("6541.48")}
atomMedian0 := sdk.DecCoin{Denom: "atom", Amount: sdk.MustNewDecFromStr("49.99")}
umeeMedian0 := sdk.DecCoin{Denom: "umee", Amount: sdk.MustNewDecFromStr("6541.48")}
atomMedian1 := sdk.DecCoin{Denom: "atom", Amount: sdk.MustNewDecFromStr("51.09")}
umeeMedian1 := sdk.DecCoin{Denom: "umee", Amount: sdk.MustNewDecFromStr("6540.23")}

app.OracleKeeper.SetMedianStampPeriod(ctx, 1)
app.OracleKeeper.SetHistoricMedian(ctx, atomMedian.Denom, uint64(ctx.BlockHeight()-1), atomMedian.Amount)
app.OracleKeeper.SetHistoricMedian(ctx, umeeMedian.Denom, uint64(ctx.BlockHeight()-1), umeeMedian.Amount)
app.OracleKeeper.SetHistoricMedian(ctx, atomMedian0.Denom, uint64(ctx.BlockHeight()-4), atomMedian0.Amount)
app.OracleKeeper.SetHistoricMedian(ctx, umeeMedian0.Denom, uint64(ctx.BlockHeight()-4), umeeMedian0.Amount)

res, err := s.queryClient.Medians(ctx.Context(), &types.QueryMedians{})
s.Require().NoError(err)
s.Require().Equal(res.Medians, sdk.NewDecCoins(atomMedian, umeeMedian))
s.Require().Equal(res.Medians, sdk.NewDecCoins(atomMedian0, umeeMedian0))

res, err = s.queryClient.Medians(ctx.Context(), &types.QueryMedians{Denom: atomMedian0.Denom, NumStamps: 1})
s.Require().NoError(err)
s.Require().Equal(res.Medians, sdk.NewDecCoins(atomMedian0))

app.OracleKeeper.SetHistoricMedian(ctx, atomMedian1.Denom, uint64(ctx.BlockHeight()-2), atomMedian1.Amount)
app.OracleKeeper.SetHistoricMedian(ctx, umeeMedian1.Denom, uint64(ctx.BlockHeight()-2), umeeMedian1.Amount)

res, err = s.queryClient.Medians(ctx.Context(), &types.QueryMedians{})
s.Require().NoError(err)
s.Require().Equal(res.Medians, sdk.DecCoins{atomMedian0, atomMedian1, umeeMedian0, umeeMedian1})

res, err = s.queryClient.Medians(ctx.Context(), &types.QueryMedians{Denom: atomMedian.Denom})
res, err = s.queryClient.Medians(ctx.Context(), &types.QueryMedians{Denom: atomMedian1.Denom, NumStamps: 2})
s.Require().NoError(err)
s.Require().Equal(res.Medians, sdk.NewDecCoins(atomMedian))
s.Require().Equal(res.Medians, sdk.DecCoins{atomMedian1, atomMedian0})

res, err = s.queryClient.Medians(ctx.Context(), &types.QueryMedians{Denom: atomMedian1.Denom, NumStamps: 0})
s.Require().ErrorContains(err, "parameter NumStamps must be greater than 0")
s.Require().Nil(res)
}

func (s *IntegrationTestSuite) TestQuerier_MedianDeviations() {
Expand Down

0 comments on commit 58a49b6

Please sign in to comment.