store.gno
18.63 Kb · 706 lines
1package staker
2
3import (
4 "errors"
5 "gno.land/p/gnoswap/store"
6 bptree "gno.land/p/nt/bptree/v0"
7 ufmt "gno.land/p/nt/ufmt/v0"
8)
9
10type StoreKey string
11
12func (s StoreKey) String() string {
13 return string(s)
14}
15
16const (
17 StoreKeyDepositGnsAmount StoreKey = "depositGnsAmount"
18 StoreKeyMinimumRewardAmount StoreKey = "minimumRewardAmount"
19 StoreKeyDeposits StoreKey = "deposits"
20 StoreKeyExternalIncentives StoreKey = "externalIncentives"
21 StoreKeyTotalEmissionSent StoreKey = "totalEmissionSent"
22 StoreKeyAllowedTokens StoreKey = "allowedTokens"
23 StoreKeyIncentiveCounter StoreKey = "incentiveCounter"
24 StoreKeyTokenSpecificMinimumRewards StoreKey = "tokenSpecificMinimumRewards"
25 StoreKeyUnstakingFee StoreKey = "unstakingFee"
26 StoreKeyPendingProtocolFees StoreKey = "pendingProtocolFees"
27 StoreKeyPools StoreKey = "pools"
28 StoreKeyPoolTierMemberships StoreKey = "poolTierMemberships"
29 StoreKeyPoolTierRatio StoreKey = "poolTierRatio"
30 StoreKeyPoolTierCounts StoreKey = "poolTierCounts"
31 StoreKeyPoolTierLastRewardCacheTimestamp StoreKey = "poolTierLastRewardCacheTimestamp"
32 StoreKeyPoolTierCurrentEmission StoreKey = "poolTierCurrentEmission"
33 StoreKeyPoolTierGetEmission StoreKey = "poolTierGetEmission"
34 StoreKeyPoolTierGetHalvingBlocksInRange StoreKey = "poolTierGetHalvingBlocksInRange"
35 StoreKeyWarmupTemplate StoreKey = "warmupTemplate"
36 StoreKeyCurrentSwapBatch StoreKey = "currentSwapBatch"
37 StoreKeyExternalIncentivesByCreationTime StoreKey = "externalIncentivesByCreationTime"
38)
39
40type stakerStore struct {
41 kvStore store.KVStore
42}
43
44// DepositGnsAmount
45func (s *stakerStore) HasDepositGnsAmountStoreKey() bool {
46 return s.kvStore.Has(StoreKeyDepositGnsAmount.String())
47}
48
49func (s *stakerStore) GetDepositGnsAmount() int64 {
50 result, err := s.kvStore.Get(StoreKeyDepositGnsAmount.String())
51 if err != nil {
52 panic(err)
53 }
54
55 amount, ok := result.(int64)
56 if !ok {
57 panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
58 }
59
60 return amount
61}
62
63func (s *stakerStore) SetDepositGnsAmount(_ int, rlm realm, amount int64) error {
64 if !rlm.IsCurrent() {
65 return errors.New(ErrSpoofedRealm)
66 }
67
68 return s.kvStore.Set(0, rlm, StoreKeyDepositGnsAmount.String(), amount)
69}
70
71// MinimumRewardAmount
72func (s *stakerStore) HasMinimumRewardAmountStoreKey() bool {
73 return s.kvStore.Has(StoreKeyMinimumRewardAmount.String())
74}
75
76func (s *stakerStore) GetMinimumRewardAmount() int64 {
77 result, err := s.kvStore.Get(StoreKeyMinimumRewardAmount.String())
78 if err != nil {
79 panic(err)
80 }
81
82 amount, ok := result.(int64)
83 if !ok {
84 panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
85 }
86
87 return amount
88}
89
90func (s *stakerStore) SetMinimumRewardAmount(_ int, rlm realm, amount int64) error {
91 if !rlm.IsCurrent() {
92 return errors.New(ErrSpoofedRealm)
93 }
94
95 return s.kvStore.Set(0, rlm, StoreKeyMinimumRewardAmount.String(), amount)
96}
97
98// Deposits
99func (s *stakerStore) HasDepositsStoreKey() bool {
100 return s.kvStore.Has(StoreKeyDeposits.String())
101}
102
103func (s *stakerStore) GetDeposits() *bptree.BPTree {
104 result, err := s.kvStore.Get(StoreKeyDeposits.String())
105 if err != nil {
106 panic(err)
107 }
108
109 deposits, ok := result.(*bptree.BPTree)
110 if !ok {
111 panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
112 }
113
114 return deposits
115}
116
117func (s *stakerStore) SetDeposits(_ int, rlm realm, deposits *bptree.BPTree) error {
118 if !rlm.IsCurrent() {
119 return errors.New(ErrSpoofedRealm)
120 }
121
122 return s.kvStore.Set(0, rlm, StoreKeyDeposits.String(), deposits)
123}
124
125// ExternalIncentives
126func (s *stakerStore) HasExternalIncentivesStoreKey() bool {
127 return s.kvStore.Has(StoreKeyExternalIncentives.String())
128}
129
130func (s *stakerStore) GetExternalIncentives() *bptree.BPTree {
131 result, err := s.kvStore.Get(StoreKeyExternalIncentives.String())
132 if err != nil {
133 panic(err)
134 }
135
136 incentives, ok := result.(*bptree.BPTree)
137 if !ok {
138 panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
139 }
140
141 return incentives
142}
143
144func (s *stakerStore) SetExternalIncentives(_ int, rlm realm, incentives *bptree.BPTree) error {
145 if !rlm.IsCurrent() {
146 return errors.New(ErrSpoofedRealm)
147 }
148
149 return s.kvStore.Set(0, rlm, StoreKeyExternalIncentives.String(), incentives)
150}
151
152// TotalEmissionSent
153func (s *stakerStore) HasTotalEmissionSentStoreKey() bool {
154 return s.kvStore.Has(StoreKeyTotalEmissionSent.String())
155}
156
157func (s *stakerStore) GetTotalEmissionSent() int64 {
158 result, err := s.kvStore.Get(StoreKeyTotalEmissionSent.String())
159 if err != nil {
160 panic(err)
161 }
162
163 amount, ok := result.(int64)
164 if !ok {
165 panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
166 }
167
168 return amount
169}
170
171func (s *stakerStore) SetTotalEmissionSent(_ int, rlm realm, amount int64) error {
172 if !rlm.IsCurrent() {
173 return errors.New(ErrSpoofedRealm)
174 }
175
176 return s.kvStore.Set(0, rlm, StoreKeyTotalEmissionSent.String(), amount)
177}
178
179// AllowedTokens
180func (s *stakerStore) HasAllowedTokensStoreKey() bool {
181 return s.kvStore.Has(StoreKeyAllowedTokens.String())
182}
183
184func (s *stakerStore) GetAllowedTokens() []string {
185 result, err := s.kvStore.Get(StoreKeyAllowedTokens.String())
186 if err != nil {
187 panic(err)
188 }
189
190 tokens, ok := result.([]string)
191 if !ok {
192 panic(ufmt.Sprintf("failed to cast result to []string: %T", result))
193 }
194
195 return cloneStringSlice(tokens)
196}
197
198func (s *stakerStore) SetAllowedTokens(_ int, rlm realm, tokens []string) error {
199 if !rlm.IsCurrent() {
200 return errors.New(ErrSpoofedRealm)
201 }
202
203 return s.kvStore.Set(0, rlm, StoreKeyAllowedTokens.String(), tokens)
204}
205
206// AddAllowedToken appends tokenPath to the allowed-tokens list when absent.
207// The store-owned slice is cloned before mutation to avoid readonly-taint panics.
208func (s *stakerStore) AddAllowedToken(_ int, rlm realm, tokenPath string) error {
209 if !rlm.IsCurrent() {
210 return errors.New(ErrSpoofedRealm)
211 }
212
213 tokens := s.GetAllowedTokens()
214 if !contains(tokens, tokenPath) {
215 tokens = append(tokens, tokenPath)
216 }
217
218 return s.kvStore.Set(0, rlm, StoreKeyAllowedTokens.String(), tokens)
219}
220
221// RemoveAllowedToken removes tokenPath from the allowed-tokens list when present.
222// The store-owned slice is cloned before mutation to avoid readonly-taint panics.
223func (s *stakerStore) RemoveAllowedToken(_ int, rlm realm, tokenPath string) error {
224 if !rlm.IsCurrent() {
225 return errors.New(ErrSpoofedRealm)
226 }
227
228 tokens := s.GetAllowedTokens()
229 for i, t := range tokens {
230 if t == tokenPath {
231 tokens = append(tokens[:i], tokens[i+1:]...)
232 break
233 }
234 }
235
236 return s.kvStore.Set(0, rlm, StoreKeyAllowedTokens.String(), tokens)
237}
238
239// IncentiveCounter
240func (s *stakerStore) HasIncentiveCounterStoreKey() bool {
241 return s.kvStore.Has(StoreKeyIncentiveCounter.String())
242}
243
244func (s *stakerStore) GetIncentiveCounter() *Counter {
245 result, err := s.kvStore.Get(StoreKeyIncentiveCounter.String())
246 if err != nil {
247 panic(err)
248 }
249
250 counter, ok := result.(*Counter)
251 if !ok {
252 panic(ufmt.Sprintf("failed to cast result to *Counter: %T", result))
253 }
254
255 return counter
256}
257
258func (s *stakerStore) SetIncentiveCounter(_ int, rlm realm, counter *Counter) error {
259 if !rlm.IsCurrent() {
260 return errors.New(ErrSpoofedRealm)
261 }
262
263 return s.kvStore.Set(0, rlm, StoreKeyIncentiveCounter.String(), counter)
264}
265
266func (s *stakerStore) NextIncentiveID(creator address, timestamp int64) string {
267 counter := s.GetIncentiveCounter()
268 return makeIncentiveID(creator, timestamp, counter.Next())
269}
270
271// TokenSpecificMinimumRewards
272func (s *stakerStore) HasTokenSpecificMinimumRewardsStoreKey() bool {
273 return s.kvStore.Has(StoreKeyTokenSpecificMinimumRewards.String())
274}
275
276func (s *stakerStore) GetTokenSpecificMinimumRewards() map[string]int64 {
277 result, err := s.kvStore.Get(StoreKeyTokenSpecificMinimumRewards.String())
278 if err != nil {
279 panic(err)
280 }
281
282 rewards, ok := result.(map[string]int64)
283 if !ok {
284 panic(ufmt.Sprintf("failed to cast result to map[string]int64: %T", result))
285 }
286
287 return rewards
288}
289
290func (s *stakerStore) SetTokenSpecificMinimumRewards(_ int, rlm realm, rewards map[string]int64) error {
291 if !rlm.IsCurrent() {
292 return errors.New(ErrSpoofedRealm)
293 }
294
295 return s.kvStore.Set(0, rlm, StoreKeyTokenSpecificMinimumRewards.String(), rewards)
296}
297
298// SetTokenSpecificMinimumRewardItem sets a single token's minimum reward amount.
299func (s *stakerStore) SetTokenSpecificMinimumRewardItem(_ int, rlm realm, tokenPath string, amount int64) error {
300 if !rlm.IsCurrent() {
301 return errors.New(ErrSpoofedRealm)
302 }
303
304 rewards := s.GetTokenSpecificMinimumRewards()
305
306 owned := make(map[string]int64)
307 for k, v := range rewards {
308 owned[k] = v
309 }
310
311 owned[tokenPath] = amount
312
313 return s.kvStore.Set(0, rlm, StoreKeyTokenSpecificMinimumRewards.String(), owned)
314}
315
316// RemoveTokenSpecificMinimumRewardItem removes a single token's minimum reward entry.
317func (s *stakerStore) RemoveTokenSpecificMinimumRewardItem(_ int, rlm realm, tokenPath string) error {
318 if !rlm.IsCurrent() {
319 return errors.New(ErrSpoofedRealm)
320 }
321
322 rewards := s.GetTokenSpecificMinimumRewards()
323
324 owned := make(map[string]int64)
325 for k, v := range rewards {
326 if k == tokenPath {
327 continue
328 }
329
330 owned[k] = v
331 }
332
333 return s.kvStore.Set(0, rlm, StoreKeyTokenSpecificMinimumRewards.String(), owned)
334}
335
336// UnstakingFee
337func (s *stakerStore) HasUnstakingFeeStoreKey() bool {
338 return s.kvStore.Has(StoreKeyUnstakingFee.String())
339}
340
341func (s *stakerStore) GetUnstakingFee() uint64 {
342 result, err := s.kvStore.Get(StoreKeyUnstakingFee.String())
343 if err != nil {
344 panic(err)
345 }
346
347 fee, ok := result.(uint64)
348 if !ok {
349 panic(ufmt.Sprintf("failed to cast result to uint64: %T", result))
350 }
351
352 return fee
353}
354
355func (s *stakerStore) SetUnstakingFee(_ int, rlm realm, fee uint64) error {
356 if !rlm.IsCurrent() {
357 return errors.New(ErrSpoofedRealm)
358 }
359
360 return s.kvStore.Set(0, rlm, StoreKeyUnstakingFee.String(), fee)
361}
362
363func (s *stakerStore) HasPendingProtocolFeesStoreKey() bool {
364 return s.kvStore.Has(StoreKeyPendingProtocolFees.String())
365}
366
367func (s *stakerStore) GetPendingProtocolFees() map[string]int64 {
368 result, err := s.kvStore.Get(StoreKeyPendingProtocolFees.String())
369 if err != nil {
370 panic(err)
371 }
372
373 fees, ok := result.(map[string]int64)
374 if !ok {
375 panic(ufmt.Sprintf("failed to cast result to map[string]int64: %T", result))
376 }
377
378 return fees
379}
380
381func (s *stakerStore) SetPendingProtocolFees(_ int, rlm realm, fees map[string]int64) error {
382 if !rlm.IsCurrent() {
383 return errors.New(ErrSpoofedRealm)
384 }
385
386 return s.kvStore.Set(0, rlm, StoreKeyPendingProtocolFees.String(), fees)
387}
388
389// Pools
390func (s *stakerStore) HasPoolsStoreKey() bool {
391 return s.kvStore.Has(StoreKeyPools.String())
392}
393
394func (s *stakerStore) GetPools() *bptree.BPTree {
395 result, err := s.kvStore.Get(StoreKeyPools.String())
396 if err != nil {
397 panic(err)
398 }
399
400 pools, ok := result.(*bptree.BPTree)
401 if !ok {
402 panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
403 }
404
405 return pools
406}
407
408func (s *stakerStore) SetPools(_ int, rlm realm, pools *bptree.BPTree) error {
409 if !rlm.IsCurrent() {
410 return errors.New(ErrSpoofedRealm)
411 }
412
413 return s.kvStore.Set(0, rlm, StoreKeyPools.String(), pools)
414}
415
416// PoolTierMemberships
417func (s *stakerStore) HasPoolTierMembershipsStoreKey() bool {
418 return s.kvStore.Has(StoreKeyPoolTierMemberships.String())
419}
420
421func (s *stakerStore) GetPoolTierMemberships() *bptree.BPTree {
422 result, err := s.kvStore.Get(StoreKeyPoolTierMemberships.String())
423 if err != nil {
424 panic(err)
425 }
426
427 memberships, ok := result.(*bptree.BPTree)
428 if !ok {
429 panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
430 }
431
432 return memberships
433}
434
435func (s *stakerStore) SetPoolTierMemberships(_ int, rlm realm, memberships *bptree.BPTree) error {
436 if !rlm.IsCurrent() {
437 return errors.New(ErrSpoofedRealm)
438 }
439
440 return s.kvStore.Set(0, rlm, StoreKeyPoolTierMemberships.String(), memberships)
441}
442
443// PoolTierRatio
444func (s *stakerStore) HasPoolTierRatioStoreKey() bool {
445 return s.kvStore.Has(StoreKeyPoolTierRatio.String())
446}
447
448func (s *stakerStore) GetPoolTierRatio() TierRatio {
449 result, err := s.kvStore.Get(StoreKeyPoolTierRatio.String())
450 if err != nil {
451 panic(err)
452 }
453
454 ratio, ok := result.(TierRatio)
455 if !ok {
456 panic(ufmt.Sprintf("failed to cast result to TierRatio: %T", result))
457 }
458
459 return ratio
460}
461
462func (s *stakerStore) SetPoolTierRatio(_ int, rlm realm, ratio TierRatio) error {
463 if !rlm.IsCurrent() {
464 return errors.New(ErrSpoofedRealm)
465 }
466
467 return s.kvStore.Set(0, rlm, StoreKeyPoolTierRatio.String(), ratio)
468}
469
470// PoolTierCounts
471func (s *stakerStore) HasPoolTierCountsStoreKey() bool {
472 return s.kvStore.Has(StoreKeyPoolTierCounts.String())
473}
474
475func (s *stakerStore) GetPoolTierCounts() [AllTierCount]uint64 {
476 result, err := s.kvStore.Get(StoreKeyPoolTierCounts.String())
477 if err != nil {
478 panic(err)
479 }
480
481 counts, ok := result.([AllTierCount]uint64)
482 if !ok {
483 panic(ufmt.Sprintf("failed to cast result to [AllTierCount]uint64: %T", result))
484 }
485
486 return counts
487}
488
489func (s *stakerStore) SetPoolTierCounts(_ int, rlm realm, counts [AllTierCount]uint64) error {
490 if !rlm.IsCurrent() {
491 return errors.New(ErrSpoofedRealm)
492 }
493
494 return s.kvStore.Set(0, rlm, StoreKeyPoolTierCounts.String(), counts)
495}
496
497// PoolTierLastRewardCacheTimestamp
498func (s *stakerStore) HasPoolTierLastRewardCacheTimestampStoreKey() bool {
499 return s.kvStore.Has(StoreKeyPoolTierLastRewardCacheTimestamp.String())
500}
501
502func (s *stakerStore) GetPoolTierLastRewardCacheTimestamp() int64 {
503 result, err := s.kvStore.Get(StoreKeyPoolTierLastRewardCacheTimestamp.String())
504 if err != nil {
505 panic(err)
506 }
507
508 timestamp, ok := result.(int64)
509 if !ok {
510 panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
511 }
512
513 return timestamp
514}
515
516func (s *stakerStore) SetPoolTierLastRewardCacheTimestamp(_ int, rlm realm, timestamp int64) error {
517 if !rlm.IsCurrent() {
518 return errors.New(ErrSpoofedRealm)
519 }
520
521 return s.kvStore.Set(0, rlm, StoreKeyPoolTierLastRewardCacheTimestamp.String(), timestamp)
522}
523
524// PoolTierCurrentEmission
525func (s *stakerStore) HasPoolTierCurrentEmissionStoreKey() bool {
526 return s.kvStore.Has(StoreKeyPoolTierCurrentEmission.String())
527}
528
529func (s *stakerStore) GetPoolTierCurrentEmission() int64 {
530 result, err := s.kvStore.Get(StoreKeyPoolTierCurrentEmission.String())
531 if err != nil {
532 panic(err)
533 }
534
535 emission, ok := result.(int64)
536 if !ok {
537 panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
538 }
539
540 return emission
541}
542
543func (s *stakerStore) SetPoolTierCurrentEmission(_ int, rlm realm, emission int64) error {
544 if !rlm.IsCurrent() {
545 return errors.New(ErrSpoofedRealm)
546 }
547
548 return s.kvStore.Set(0, rlm, StoreKeyPoolTierCurrentEmission.String(), emission)
549}
550
551// PoolTierGetEmission
552func (s *stakerStore) HasPoolTierGetEmissionStoreKey() bool {
553 return s.kvStore.Has(StoreKeyPoolTierGetEmission.String())
554}
555
556func (s *stakerStore) GetPoolTierGetEmission() func() int64 {
557 result, err := s.kvStore.Get(StoreKeyPoolTierGetEmission.String())
558 if err != nil {
559 panic(err)
560 }
561
562 fn, ok := result.(func() int64)
563 if !ok {
564 panic(ufmt.Sprintf("failed to cast result to func() int64: %T", result))
565 }
566
567 return fn
568}
569
570func (s *stakerStore) SetPoolTierGetEmission(_ int, rlm realm, fn func() int64) error {
571 if !rlm.IsCurrent() {
572 return errors.New(ErrSpoofedRealm)
573 }
574
575 return s.kvStore.Set(0, rlm, StoreKeyPoolTierGetEmission.String(), fn)
576}
577
578// PoolTierGetHalvingBlocksInRange
579func (s *stakerStore) HasPoolTierGetHalvingBlocksInRangeStoreKey() bool {
580 return s.kvStore.Has(StoreKeyPoolTierGetHalvingBlocksInRange.String())
581}
582
583func (s *stakerStore) GetPoolTierGetHalvingBlocksInRange() func(start, end int64) ([]int64, []int64) {
584 result, err := s.kvStore.Get(StoreKeyPoolTierGetHalvingBlocksInRange.String())
585 if err != nil {
586 panic(err)
587 }
588
589 fn, ok := result.(func(start, end int64) ([]int64, []int64))
590 if !ok {
591 panic(ufmt.Sprintf("failed to cast result to func(start, end int64) ([]int64, []int64): %T", result))
592 }
593
594 return fn
595}
596
597func (s *stakerStore) SetPoolTierGetHalvingBlocksInRange(_ int, rlm realm, fn func(start, end int64) ([]int64, []int64)) error {
598 if !rlm.IsCurrent() {
599 return errors.New(ErrSpoofedRealm)
600 }
601
602 return s.kvStore.Set(0, rlm, StoreKeyPoolTierGetHalvingBlocksInRange.String(), fn)
603}
604
605func (s *stakerStore) HasWarmupTemplateStoreKey() bool {
606 return s.kvStore.Has(StoreKeyWarmupTemplate.String())
607}
608
609func (s *stakerStore) GetWarmupTemplate() []Warmup {
610 result, err := s.kvStore.Get(StoreKeyWarmupTemplate.String())
611 if err != nil {
612 panic(err)
613 }
614
615 warmups, ok := result.([]Warmup)
616 if !ok {
617 panic(ufmt.Sprintf("failed to cast result to []Warmup: %T", result))
618 }
619
620 return cloneWarmups(warmups)
621}
622
623func (s *stakerStore) SetWarmupTemplate(_ int, rlm realm, warmups []Warmup) error {
624 if !rlm.IsCurrent() {
625 return errors.New(ErrSpoofedRealm)
626 }
627
628 return s.kvStore.Set(0, rlm, StoreKeyWarmupTemplate.String(), warmups)
629}
630
631// CurrentSwapBatch
632func (s *stakerStore) HasCurrentSwapBatchStoreKey() bool {
633 return s.kvStore.Has(StoreKeyCurrentSwapBatch.String())
634}
635
636func (s *stakerStore) GetCurrentSwapBatch() *SwapBatchProcessor {
637 result, err := s.kvStore.Get(StoreKeyCurrentSwapBatch.String())
638 if err != nil {
639 panic(err)
640 }
641
642 batch, ok := result.(*SwapBatchProcessor)
643 if !ok {
644 panic(ufmt.Sprintf("failed to cast result to *SwapBatchProcessor: %T", result))
645 }
646
647 return batch
648}
649
650func (s *stakerStore) SetCurrentSwapBatch(_ int, rlm realm, batch *SwapBatchProcessor) error {
651 if !rlm.IsCurrent() {
652 return errors.New(ErrSpoofedRealm)
653 }
654
655 return s.kvStore.Set(0, rlm, StoreKeyCurrentSwapBatch.String(), batch)
656}
657
658// ExternalIncentivesByCreationTime
659// key: timestamp -> value: *bptree.BPTree (poolPath -> []string)
660func (s *stakerStore) HasExternalIncentivesByCreationTimeStoreKey() bool {
661 return s.kvStore.Has(StoreKeyExternalIncentivesByCreationTime.String())
662}
663
664func (s *stakerStore) GetExternalIncentivesByCreationTime() *UintTree {
665 result, err := s.kvStore.Get(StoreKeyExternalIncentivesByCreationTime.String())
666 if err != nil {
667 panic(err)
668 }
669
670 tree, ok := result.(*UintTree)
671 if !ok {
672 panic(ufmt.Sprintf("failed to cast result to *UintTree: %T", result))
673 }
674
675 return tree
676}
677
678func (s *stakerStore) SetExternalIncentivesByCreationTime(_ int, rlm realm, tree *UintTree) error {
679 if !rlm.IsCurrent() {
680 return errors.New(ErrSpoofedRealm)
681 }
682
683 return s.kvStore.Set(0, rlm, StoreKeyExternalIncentivesByCreationTime.String(), tree)
684}
685
686// NewStakerStore creates a new staker store instance with the provided KV store.
687// This function is used by the upgrade system to create storage instances for each implementation.
688func NewStakerStore(kvStore store.KVStore) IStakerStore {
689 return &stakerStore{
690 kvStore: kvStore,
691 }
692}
693
694func makeIncentiveID(creator address, timestamp int64, index int64) string {
695 return ufmt.Sprintf("%s:%d:%d", creator.String(), timestamp, index)
696}
697
698func contains(items []string, item string) bool {
699 for _, i := range items {
700 if i == item {
701 return true
702 }
703 }
704
705 return false
706}