-
Notifications
You must be signed in to change notification settings - Fork 44
/
price.go
137 lines (112 loc) · 3.73 KB
/
price.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package keeper
import (
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/elys-network/elys/x/oracle/types"
)
// SetPrice set a specific price in the store from its index
func (k Keeper) SetPrice(ctx sdk.Context, price types.Price) {
store := ctx.KVStore(k.storeKey)
b := k.cdc.MustMarshal(&price)
store.Set(types.PriceKey(price.Asset, price.Source, price.Timestamp), b)
}
// GetPrice returns a price from its index
func (k Keeper) GetPrice(ctx sdk.Context, asset, source string, timestamp uint64) (val types.Price, found bool) {
store := ctx.KVStore(k.storeKey)
b := store.Get(types.PriceKey(asset, source, timestamp))
if b == nil {
return val, false
}
k.cdc.MustUnmarshal(b, &val)
return val, true
}
func (k Keeper) GetLatestPriceFromAssetAndSource(ctx sdk.Context, asset, source string) (val types.Price, found bool) {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStoreReversePrefixIterator(store, types.PriceKeyPrefixAssetAndSource(asset, source))
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var val types.Price
k.cdc.MustUnmarshal(iterator.Value(), &val)
return val, true
}
return val, false
}
func (k Keeper) GetLatestPriceFromAnySource(ctx sdk.Context, asset string) (val types.Price, found bool) {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStoreReversePrefixIterator(store, types.PriceKeyPrefixAsset(asset))
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var val types.Price
k.cdc.MustUnmarshal(iterator.Value(), &val)
return val, true
}
return val, false
}
// RemovePrice removes a price from the store
func (k Keeper) RemovePrice(ctx sdk.Context, asset, source string, timestamp uint64) {
store := ctx.KVStore(k.storeKey)
store.Delete(types.PriceKey(asset, source, timestamp))
}
// GetAllPrice returns all price
func (k Keeper) GetAllPrice(ctx sdk.Context) (list []types.Price) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PriceKeyPrefix))
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var val types.Price
k.cdc.MustUnmarshal(iterator.Value(), &val)
list = append(list, val)
}
return
}
// MigrateAllLegacyPrices migrates all legacy prices
func (k Keeper) MigrateAllLegacyPrices(ctx sdk.Context) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.PriceKeyPrefix))
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var val types.LegacyPrice
k.cdc.MustUnmarshal(iterator.Value(), &val)
k.SetPrice(ctx, types.Price{
Asset: val.Asset,
Price: val.Price,
Source: val.Source,
Provider: val.Provider,
Timestamp: val.Timestamp,
BlockHeight: uint64(ctx.BlockHeight()),
})
}
return
}
func (k Keeper) GetAssetPrice(ctx sdk.Context, asset string) (types.Price, bool) {
// try out elys source
val, found := k.GetLatestPriceFromAssetAndSource(ctx, asset, types.ELYS)
if found {
return val, true
}
// try out band source
val, found = k.GetLatestPriceFromAssetAndSource(ctx, asset, types.BAND)
if found {
return val, true
}
// find from any source if band source does not exist
return k.GetLatestPriceFromAnySource(ctx, asset)
}
func Pow10(decimal uint64) (value sdk.Dec) {
value = sdk.NewDec(1)
for i := 0; i < int(decimal); i++ {
value = value.Mul(sdk.NewDec(10))
}
return
}
func (k Keeper) GetAssetPriceFromDenom(ctx sdk.Context, denom string) sdk.Dec {
info, found := k.GetAssetInfo(ctx, denom)
if !found {
return sdk.ZeroDec()
}
price, found := k.GetAssetPrice(ctx, info.Display)
if !found {
return sdk.ZeroDec()
}
return price.Price.Quo(Pow10(info.Decimal))
}