@@ -54,23 +54,22 @@ func (k Keeper) SetPrice(ctx sdk.Context, price types.Price) {
54
54
ctx .KVStore (k .storeKey ).Set (types .PriceStoreKey (price .SignalID ), k .cdc .MustMarshal (& price ))
55
55
}
56
56
57
- // DeletePrice deletes a price by signal id.
58
- func (k Keeper ) DeletePrice (ctx sdk.Context , signalID string ) {
59
- ctx .KVStore (k .storeKey ).Delete (types .PriceStoreKey (signalID ))
60
- }
61
-
62
57
// CalculatePrices calculates final prices for all supported feeds.
63
58
func (k Keeper ) CalculatePrices (ctx sdk.Context ) {
59
+ // get the current feeds
64
60
currentFeeds := k .GetCurrentFeeds (ctx )
65
61
66
62
var validatorsByPower []types.ValidatorInfo
63
+ // iterate over bonded validators sorted by power
67
64
k .stakingKeeper .IterateBondedValidatorsByPower (
68
65
ctx ,
69
66
func (idx int64 , val stakingtypes.ValidatorI ) (stop bool ) {
67
+ // get the status of the validator
70
68
status := k .oracleKeeper .GetValidatorStatus (ctx , val .GetOperator ())
71
69
if ! status .IsActive {
72
70
return false
73
71
}
72
+ // collect validator information
74
73
validatorInfo := types.ValidatorInfo {
75
74
Index : idx ,
76
75
Address : val .GetOperator (),
@@ -81,6 +80,7 @@ func (k Keeper) CalculatePrices(ctx sdk.Context) {
81
80
return false
82
81
})
83
82
83
+ // collect all validator prices
84
84
allValidatorPrices := make (map [string ]map [string ]types.ValidatorPrice )
85
85
for _ , val := range validatorsByPower {
86
86
valPricesList , err := k .GetValidatorPriceList (ctx , val .Address )
@@ -90,20 +90,22 @@ func (k Keeper) CalculatePrices(ctx sdk.Context) {
90
90
91
91
valPricesMap := make (map [string ]types.ValidatorPrice )
92
92
for _ , valPrice := range valPricesList .ValidatorPrices {
93
- if valPrice .SignalID != "" {
93
+ if valPrice .PriceStatus != types . PriceStatusUnspecified {
94
94
valPricesMap [valPrice .SignalID ] = valPrice
95
95
}
96
96
}
97
97
98
98
allValidatorPrices [val .Address .String ()] = valPricesMap
99
99
}
100
100
101
+ // calculate prices for each feed
101
102
for _ , feed := range currentFeeds .Feeds {
102
103
var priceFeedInfos []types.PriceFeedInfo
103
104
for _ , valInfo := range validatorsByPower {
104
105
valPrice := allValidatorPrices [valInfo .Address .String ()][feed .SignalID ]
105
106
106
- missReport , havePrice := CheckMissReport (
107
+ // check for miss report
108
+ missReport := CheckMissReport (
107
109
feed ,
108
110
currentFeeds .LastUpdateTimestamp ,
109
111
currentFeeds .LastUpdateBlock ,
@@ -117,6 +119,8 @@ func (k Keeper) CalculatePrices(ctx sdk.Context) {
117
119
k .oracleKeeper .MissReport (ctx , valInfo .Address , ctx .BlockTime ())
118
120
}
119
121
122
+ // check if the price is available
123
+ havePrice := CheckHavePrice (feed , valPrice , ctx .BlockTime ())
120
124
if havePrice {
121
125
priceFeedInfos = append (
122
126
priceFeedInfos , types.PriceFeedInfo {
@@ -130,8 +134,10 @@ func (k Keeper) CalculatePrices(ctx sdk.Context) {
130
134
}
131
135
}
132
136
137
+ // calculate the final price for the feed
133
138
price , err := k .CalculatePrice (ctx , feed , priceFeedInfos )
134
139
if err != nil {
140
+ // emit event for failed price calculation
135
141
ctx .EventManager ().EmitEvent (
136
142
sdk .NewEvent (
137
143
types .EventTypeCalculatePriceFailed ,
@@ -142,8 +148,10 @@ func (k Keeper) CalculatePrices(ctx sdk.Context) {
142
148
continue
143
149
}
144
150
151
+ // set the calculated price in the store
145
152
k .SetPrice (ctx , price )
146
153
154
+ // emit event for updated price
147
155
ctx .EventManager ().EmitEvent (
148
156
sdk .NewEvent (
149
157
types .EventTypeUpdatePrice ,
@@ -213,35 +221,42 @@ func CheckMissReport(
213
221
blockTime time.Time ,
214
222
blockHeight int64 ,
215
223
gracePeriod int64 ,
216
- ) ( missReport bool , havePrice bool ) {
217
- // During the grace period, if the block time exceeds MaximumGuaranteeBlockTime , it will be capped at MaximumGuaranteeBlockTime .
224
+ ) bool {
225
+ // During the grace period, if the block time exceeds MaxGuaranteeBlockTime , it will be capped at MaxGuaranteeBlockTime .
218
226
// This means that in cases of slow block time, the validator will not be deactivated
219
- // as long as the block height does not exceed the equivalent of assumed MaximumGuaranteeBlockTime of block time.
227
+ // as long as the block height does not exceed the equivalent of assumed MaxGuaranteeBlockTime of block time.
220
228
lastTime := lastUpdateTimestamp + gracePeriod
221
- lastBlock := lastUpdateBlock + gracePeriod / types .MaximumGuaranteeBlockTime
229
+ lastBlock := lastUpdateBlock + gracePeriod / types .MaxGuaranteeBlockTime
222
230
223
231
if valInfo .Status .Since .Unix ()+ gracePeriod > lastTime {
224
232
lastTime = valInfo .Status .Since .Unix () + gracePeriod
225
233
}
226
234
227
- if valPrice .SignalID != "" {
228
- // Append valid price feed info if within the acceptance period
229
- if valPrice .Timestamp >= blockTime .Unix ()- feed .Interval {
230
- havePrice = true
231
- }
232
-
235
+ if valPrice .PriceStatus != types .PriceStatusUnspecified {
233
236
if valPrice .Timestamp + feed .Interval > lastTime {
234
237
lastTime = valPrice .Timestamp + feed .Interval
235
238
}
236
239
237
- if valPrice .BlockHeight + feed .Interval / types .MaximumGuaranteeBlockTime > lastBlock {
238
- lastBlock = valPrice .BlockHeight + feed .Interval / types .MaximumGuaranteeBlockTime
240
+ if valPrice .BlockHeight + feed .Interval / types .MaxGuaranteeBlockTime > lastBlock {
241
+ lastBlock = valPrice .BlockHeight + feed .Interval / types .MaxGuaranteeBlockTime
239
242
}
240
243
}
241
244
242
245
// Determine if the last action is too old, indicating a missed report
243
- missReport = lastTime < blockTime .Unix () && lastBlock < blockHeight
244
- return
246
+ return lastTime < blockTime .Unix () && lastBlock < blockHeight
247
+ }
248
+
249
+ // CheckHavePrice checks if a validator has a price feed within interval range.
250
+ func CheckHavePrice (
251
+ feed types.Feed ,
252
+ valPrice types.ValidatorPrice ,
253
+ blockTime time.Time ,
254
+ ) bool {
255
+ if valPrice .PriceStatus != types .PriceStatusUnspecified && valPrice .Timestamp >= blockTime .Unix ()- feed .Interval {
256
+ return true
257
+ }
258
+
259
+ return false
245
260
}
246
261
247
262
// GetValidatorPriceList gets a validator price by validator address.
@@ -275,3 +290,21 @@ func (k Keeper) SetValidatorPriceList(
275
290
276
291
return nil
277
292
}
293
+
294
+ // ValidateValidatorRequiredToSend validates validator is required for price submission.
295
+ func (k Keeper ) ValidateValidatorRequiredToSend (
296
+ ctx sdk.Context ,
297
+ val sdk.ValAddress ,
298
+ ) error {
299
+ isValid := k .IsBondedValidator (ctx , val )
300
+ if ! isValid {
301
+ return types .ErrNotBondedValidator
302
+ }
303
+
304
+ status := k .oracleKeeper .GetValidatorStatus (ctx , val )
305
+ if ! status .IsActive {
306
+ return types .ErrOracleStatusNotActive .Wrapf ("val: %s" , val .String ())
307
+ }
308
+
309
+ return nil
310
+ }
0 commit comments