Skip to content

Commit dc63829

Browse files
authored
updating oracle end blocker to have only latest price and optimizations (#1333)
* optimizing oracle module asset price * adding unit test cases * updating oracle end blocker to have only latest price * updating comment
1 parent 16a87e8 commit dc63829

File tree

18 files changed

+331
-92
lines changed

18 files changed

+331
-92
lines changed

app/setup_handlers.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,9 @@ import (
1313
)
1414

1515
const (
16-
LocalNetVersion = "v999999"
17-
NewMaxBytes = 5 * 1024 * 1024 // 5MB
16+
NewMaxBytes = 5 * 1024 * 1024 // 5MB
1817
)
1918

20-
// make sure to update these when you upgrade the version
21-
var NextVersion = "vNEXT"
22-
2319
// generate upgrade version from the current version (v999999.999999.999999 => v999999)
2420
func generateUpgradeVersion() string {
2521
currentVersion := version.Version
@@ -68,6 +64,8 @@ func (app *ElysApp) setUpgradeHandler() {
6864

6965
vm, vmErr := app.mm.RunMigrations(ctx, app.configurator, vm)
7066

67+
app.OracleKeeper.EndBlock(ctx)
68+
7169
//oracleParams := app.OracleKeeper.GetParams(ctx)
7270
//if len(oracleParams.MandatoryList) == 0 {
7371
// err := app.ojoOracleMigration(ctx, plan.Height+1)

x/amm/types/expected_keepers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ type BankKeeper interface {
4040
//
4141
//go:generate mockery --srcpkg . --name OracleKeeper --structname OracleKeeper --filename oracle_keeper.go --with-expecter
4242
type OracleKeeper interface {
43-
GetAssetPrice(ctx sdk.Context, asset string) (osmomath.BigDec, bool)
43+
GetAssetPrice(ctx sdk.Context, asset string) (sdkmath.LegacyDec, bool)
4444
GetDenomPrice(ctx sdk.Context, denom string) osmomath.BigDec
4545
GetPriceFeeder(ctx sdk.Context, feeder sdk.AccAddress) (val oracletypes.PriceFeeder, found bool)
4646
//SetPool(ctx sdk.Context, pool oracletypes.Pool)

x/amm/types/mocks/accounted_pool_keeper.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x/amm/types/mocks/oracle_keeper.go

Lines changed: 9 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

x/masterchef/types/expected_keepers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ type AmmKeeper interface {
9999

100100
// OracleKeeper defines the expected interface needed to retrieve price info
101101
type OracleKeeper interface {
102-
GetAssetPrice(ctx sdk.Context, asset string) (osmomath.BigDec, bool)
102+
GetAssetPrice(ctx sdk.Context, asset string) (math.LegacyDec, bool)
103103
GetDenomPrice(ctx sdk.Context, denom string) osmomath.BigDec
104104
GetPriceFeeder(ctx sdk.Context, feeder sdk.AccAddress) (val oracletypes.PriceFeeder, found bool)
105105
//SetPool(ctx sdk.Context, pool oracletypes.Pool)

x/oracle/keeper/abci.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,28 @@ package keeper
22

33
import (
44
sdk "github.com/cosmos/cosmos-sdk/types"
5+
"sort"
56
)
67

78
func (k Keeper) EndBlock(ctx sdk.Context) {
8-
// Remove outdated prices
9-
params := k.GetParams(ctx)
10-
for _, price := range k.GetAllPrice(ctx) {
11-
if price.Timestamp+params.PriceExpiryTime < uint64(ctx.BlockTime().Unix()) || price.BlockHeight+params.LifeTimeInBlocks < uint64(ctx.BlockHeight()) {
12-
k.RemovePrice(ctx, price.Asset, price.Source, price.Timestamp)
9+
10+
assetInfos := k.GetAllAssetInfo(ctx)
11+
12+
for _, info := range assetInfos {
13+
allAssetPrice := k.GetAllAssetPrice(ctx, info.Display)
14+
total := len(allAssetPrice)
15+
16+
// Need to sort it because order fetched from GetAllAssetPrice will not be in ascending order - depending on source
17+
// If we remove the source then this should not be needed
18+
sort.Slice(allAssetPrice, func(i, j int) bool {
19+
return allAssetPrice[i].Timestamp < allAssetPrice[j].Timestamp
20+
})
21+
22+
for i, price := range allAssetPrice {
23+
// We don't remove the last element
24+
if i < total-1 {
25+
k.RemovePrice(ctx, price.Asset, price.Source, price.Timestamp)
26+
}
1327
}
1428
}
1529
}

x/oracle/keeper/abci_test.go

Lines changed: 86 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,113 @@
11
package keeper_test
22

33
import (
4-
"time"
5-
64
sdkmath "cosmossdk.io/math"
5+
"sort"
76

87
"github.com/elys-network/elys/v6/x/oracle/types"
98
)
109

1110
// This test ensures old price data is automatically removed
1211
func (suite *KeeperTestSuite) TestEndBlock() {
13-
now := time.Now()
14-
params := types.DefaultParams()
15-
suite.app.OracleKeeper.SetParams(suite.ctx, params)
16-
17-
prices := []types.Price{
12+
btcPriceData := []types.Price{
1813
{
1914
Asset: "BTC",
20-
Price: sdkmath.LegacyNewDec(1),
15+
Price: sdkmath.LegacyNewDec(23),
2116
Source: "elys",
22-
Timestamp: uint64(now.Unix()),
17+
Timestamp: 20,
2318
},
2419
{
2520
Asset: "BTC",
26-
Price: sdkmath.LegacyNewDec(2),
21+
Price: sdkmath.LegacyNewDec(12),
2722
Source: "band",
28-
Timestamp: uint64(now.Unix()) + params.PriceExpiryTime,
23+
Timestamp: 10,
24+
},
25+
{
26+
Asset: "BTC",
27+
Price: sdkmath.LegacyNewDec(76),
28+
Source: "elys",
29+
Timestamp: 40,
2930
},
3031
{
3132
Asset: "BTC",
32-
Price: sdkmath.LegacyNewDec(3),
33+
Price: sdkmath.LegacyNewDec(55),
3334
Source: "band",
34-
Timestamp: uint64(now.Unix()) + params.PriceExpiryTime,
35+
Timestamp: 30,
36+
},
37+
{
38+
Asset: "BTC",
39+
Price: sdkmath.LegacyNewDec(89),
40+
Source: "random",
41+
Timestamp: 25,
3542
},
3643
}
37-
for _, price := range prices {
44+
ethPriceData := []types.Price{
45+
{
46+
Asset: "ETH",
47+
Price: sdkmath.LegacyNewDec(23),
48+
Source: "elys",
49+
Timestamp: 34,
50+
},
51+
{
52+
Asset: "ETH",
53+
Price: sdkmath.LegacyNewDec(12),
54+
Source: "band",
55+
Timestamp: 23,
56+
},
57+
{
58+
Asset: "ETH",
59+
Price: sdkmath.LegacyNewDec(76),
60+
Source: "elys",
61+
Timestamp: 89,
62+
},
63+
{
64+
Asset: "ETH",
65+
Price: sdkmath.LegacyNewDec(55),
66+
Source: "random",
67+
Timestamp: 54,
68+
},
69+
{
70+
Asset: "ETH",
71+
Price: sdkmath.LegacyNewDec(89),
72+
Source: "band",
73+
Timestamp: 76,
74+
},
75+
}
76+
suite.app.OracleKeeper.SetAssetInfo(suite.ctx, types.AssetInfo{
77+
Denom: "satoshi",
78+
Display: "BTC",
79+
BandTicker: "BTC",
80+
ElysTicker: "BTC",
81+
Decimal: 8,
82+
})
83+
suite.app.OracleKeeper.SetAssetInfo(suite.ctx, types.AssetInfo{
84+
Denom: "wei",
85+
Display: "ETH",
86+
BandTicker: "ETH",
87+
ElysTicker: "ETH",
88+
Decimal: 18,
89+
})
90+
for _, price := range btcPriceData {
91+
suite.app.OracleKeeper.SetPrice(suite.ctx, price)
92+
}
93+
for _, price := range ethPriceData {
3894
suite.app.OracleKeeper.SetPrice(suite.ctx, price)
3995
}
40-
suite.ctx = suite.ctx.WithBlockTime(now.Add(time.Second * time.Duration(params.PriceExpiryTime)))
4196

42-
prices = suite.app.OracleKeeper.GetAllPrice(suite.ctx)
43-
suite.Require().Len(prices, 2)
97+
suite.app.OracleKeeper.EndBlock(suite.ctx)
98+
99+
sort.Slice(btcPriceData, func(i, j int) bool {
100+
return btcPriceData[i].Timestamp < btcPriceData[j].Timestamp
101+
})
102+
sort.Slice(ethPriceData, func(i, j int) bool {
103+
return ethPriceData[i].Timestamp < ethPriceData[j].Timestamp
104+
})
105+
106+
allPrices := suite.app.OracleKeeper.GetAllAssetPrice(suite.ctx, "BTC")
107+
suite.Require().Equal(1, len(allPrices))
108+
suite.Require().Equal(btcPriceData[len(btcPriceData)-1], allPrices[0])
109+
110+
allPrices = suite.app.OracleKeeper.GetAllAssetPrice(suite.ctx, "ETH")
111+
suite.Require().Equal(1, len(allPrices))
112+
suite.Require().Equal(ethPriceData[len(ethPriceData)-1], allPrices[0])
44113
}

x/oracle/keeper/price.go

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package keeper
22

33
import (
4+
"cosmossdk.io/math"
45
"cosmossdk.io/store/prefix"
56
storetypes "cosmossdk.io/store/types"
67
"github.com/cosmos/cosmos-sdk/runtime"
@@ -80,48 +81,40 @@ func (k Keeper) GetAllPrice(ctx sdk.Context) (list []types.Price) {
8081
return
8182
}
8283

83-
// MigrateAllLegacyPrices migrates all legacy prices
84-
func (k Keeper) MigrateAllLegacyPrices(ctx sdk.Context) {
85-
store := prefix.NewStore(runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)), types.KeyPrefix(types.PriceKeyPrefix))
84+
func (k Keeper) GetAllAssetPrice(ctx sdk.Context, asset string) (list []types.Price) {
85+
store := prefix.NewStore(runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx)), types.PriceKeyPrefixAsset(asset))
8686
iterator := storetypes.KVStorePrefixIterator(store, []byte{})
8787

8888
defer iterator.Close()
8989

9090
for ; iterator.Valid(); iterator.Next() {
91-
var val types.LegacyPrice
91+
var val types.Price
9292
k.cdc.MustUnmarshal(iterator.Value(), &val)
93-
k.SetPrice(ctx, types.Price{
94-
Asset: val.Asset,
95-
Price: val.Price,
96-
Source: val.Source,
97-
Provider: val.Provider,
98-
Timestamp: val.Timestamp,
99-
BlockHeight: uint64(ctx.BlockHeight()),
100-
})
93+
list = append(list, val)
10194
}
10295

10396
return
10497
}
10598

106-
func (k Keeper) GetAssetPrice(ctx sdk.Context, asset string) (osmomath.BigDec, bool) {
99+
func (k Keeper) GetAssetPrice(ctx sdk.Context, asset string) (math.LegacyDec, bool) {
107100
// try out elys source
108101
val, found := k.GetLatestPriceFromAssetAndSource(ctx, asset, types.ELYS)
109102
if found {
110-
return osmomath.BigDecFromDec(val.Price), true
103+
return val.Price, true
111104
}
112105

113106
// try out band source
114107
val, found = k.GetLatestPriceFromAssetAndSource(ctx, asset, types.BAND)
115108
if found {
116-
return osmomath.BigDecFromDec(val.Price), true
109+
return val.Price, true
117110
}
118111

119112
// find from any source if band source does not exist
120113
price, found := k.GetLatestPriceFromAnySource(ctx, asset)
121114
if found {
122-
return osmomath.BigDecFromDec(price.Price), true
115+
return price.Price, true
123116
}
124-
return osmomath.BigDec{}, false
117+
return math.LegacyDec{}, false
125118
}
126119

127120
func (k Keeper) GetDenomPrice(ctx sdk.Context, denom string) osmomath.BigDec {
@@ -134,7 +127,7 @@ func (k Keeper) GetDenomPrice(ctx sdk.Context, denom string) osmomath.BigDec {
134127
return osmomath.ZeroBigDec()
135128
}
136129
if info.Decimal <= 18 {
137-
return price.QuoInt64(utils.Pow10Int64(info.Decimal))
130+
return osmomath.BigDecFromDec(price).QuoInt64(utils.Pow10Int64(info.Decimal))
138131
}
139-
return price.Quo(utils.Pow10(info.Decimal))
132+
return osmomath.BigDecFromDec(price).Quo(utils.Pow10(info.Decimal))
140133
}

0 commit comments

Comments
 (0)