Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

store.gno

19.10 Kb · 584 lines
  1package staker
  2
  3import (
  4	"errors"
  5
  6	"gno.land/p/gnoswap/store/v1"
  7	"gno.land/p/gnoswap/utils/v1"
  8	bptree "gno.land/p/nt/bptree/v0"
  9	ufmt "gno.land/p/nt/ufmt/v0"
 10)
 11
 12// Storage key constants
 13const (
 14	// Basic configuration
 15	StoreKeyUnDelegationLockupPeriod = "unDelegationLockupPeriod"
 16	StoreKeyTotalDelegatedAmount     = "totalDelegatedAmount"
 17	StoreKeyTotalLockedAmount        = "totalLockedAmount"
 18
 19	// Counters
 20	StoreKeyDelegationNextID = "delegationNextID"
 21
 22	// Complex data structures
 23	StoreKeyDelegations            = "delegations"            // BPTree of delegations
 24	StoreKeyTotalDelegationHistory = "totalDelegationHistory" // UintTree: timestamp -> int64 (cumulative total)
 25	StoreKeyUserDelegationHistory  = "userDelegationHistory"  // BPTree: address -> *UintTree[timestamp -> int64]
 26
 27	// Manager states
 28	StoreKeyEmissionRewardManager    = "emissionRewardManager"
 29	StoreKeyProtocolFeeRewardManager = "protocolFeeRewardManager"
 30	StoreKeyDelegationManager        = "delegationManager"
 31	StoreKeyLaunchpadProjectDeposits = "launchpadProjectDeposits"
 32)
 33
 34// govStakerStore is the concrete implementation of IGovStakerStore
 35type govStakerStore struct {
 36	kvStore store.KVStore
 37}
 38
 39var _ IGovStakerStore = (*govStakerStore)(nil)
 40
 41// NewGovStakerStore creates a new governance staker store instance backed by kvStore.
 42//
 43// Parameters:
 44//   - kvStore: Key-value store used to persist governance staker state.
 45//
 46// Returns:
 47//   - IGovStakerStore: store implementation that reads and writes the supplied KV store.
 48func NewGovStakerStore(kvStore store.KVStore) IGovStakerStore {
 49	return &govStakerStore{
 50		kvStore: kvStore,
 51	}
 52}
 53
 54// Basic configuration methods
 55// Returns:
 56//   - bool: true when the undelegation lockup-period key is present in storage.
 57func (s *govStakerStore) HasUnDelegationLockupPeriodStoreKey() bool {
 58	return s.kvStore.Has(StoreKeyUnDelegationLockupPeriod)
 59}
 60
 61// GetUnDelegationLockupPeriod returns the configured undelegation lockup period in seconds.
 62//
 63// Returns:
 64//   - int64: lockup duration in seconds; panics if the stored value is unavailable or not int64.
 65func (s *govStakerStore) GetUnDelegationLockupPeriod() int64 {
 66	result, err := s.kvStore.Get(StoreKeyUnDelegationLockupPeriod)
 67	if err != nil {
 68		panic(err)
 69	}
 70
 71	period, ok := result.(int64)
 72	if !ok {
 73		panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
 74	}
 75
 76	return period
 77}
 78
 79// SetUnDelegationLockupPeriod stores the undelegation lockup period.
 80//
 81// Parameters:
 82//   - _: Internal call discriminator; pass 0.
 83//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
 84//   - period: Undelegation lockup duration in seconds.
 85//
 86// Returns:
 87//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
 88func (s *govStakerStore) SetUnDelegationLockupPeriod(_ int, rlm realm, period int64) error {
 89	if !rlm.IsCurrent() {
 90		return errors.New(ErrSpoofedRealm)
 91	}
 92
 93	return s.kvStore.Set(0, rlm, StoreKeyUnDelegationLockupPeriod, period)
 94}
 95
 96// Returns:
 97//   - bool: true when the total delegated-amount key is present in storage.
 98func (s *govStakerStore) HasTotalDelegatedAmountStoreKey() bool {
 99	return s.kvStore.Has(StoreKeyTotalDelegatedAmount)
100}
101
102// GetTotalDelegatedAmount returns the total amount currently delegated.
103//
104// Returns:
105//   - int64: aggregate delegated amount; panics if the stored value is unavailable or not int64.
106func (s *govStakerStore) GetTotalDelegatedAmount() int64 {
107	result, err := s.kvStore.Get(StoreKeyTotalDelegatedAmount)
108	if err != nil {
109		panic(err)
110	}
111
112	amount, ok := result.(int64)
113	if !ok {
114		panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
115	}
116
117	return amount
118}
119
120// SetTotalDelegatedAmount stores the aggregate delegated amount.
121//
122// Parameters:
123//   - _: Internal call discriminator; pass 0.
124//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
125//   - amount: Aggregate amount of GNS delegated across all delegators.
126//
127// Returns:
128//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
129func (s *govStakerStore) SetTotalDelegatedAmount(_ int, rlm realm, amount int64) error {
130	if !rlm.IsCurrent() {
131		return errors.New(ErrSpoofedRealm)
132	}
133
134	return s.kvStore.Set(0, rlm, StoreKeyTotalDelegatedAmount, amount)
135}
136
137// Returns:
138//   - bool: true when the total locked-amount key is present in storage.
139func (s *govStakerStore) HasTotalLockedAmountStoreKey() bool {
140	return s.kvStore.Has(StoreKeyTotalLockedAmount)
141}
142
143// GetTotalLockedAmount returns the total amount locked in undelegation withdrawals.
144//
145// Returns:
146//   - int64: aggregate locked amount; panics if the stored value is unavailable or not int64.
147func (s *govStakerStore) GetTotalLockedAmount() int64 {
148	result, err := s.kvStore.Get(StoreKeyTotalLockedAmount)
149	if err != nil {
150		panic(err)
151	}
152
153	amount, ok := result.(int64)
154	if !ok {
155		panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
156	}
157
158	return amount
159}
160
161// SetTotalLockedAmount stores the aggregate amount locked in undelegation.
162//
163// Parameters:
164//   - _: Internal call discriminator; pass 0.
165//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
166//   - amount: Aggregate GNS amount currently locked in undelegation withdrawals.
167//
168// Returns:
169//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
170func (s *govStakerStore) SetTotalLockedAmount(_ int, rlm realm, amount int64) error {
171	if !rlm.IsCurrent() {
172		return errors.New(ErrSpoofedRealm)
173	}
174
175	return s.kvStore.Set(0, rlm, StoreKeyTotalLockedAmount, amount)
176}
177
178// Delegation management methods
179// Returns:
180//   - bool: true when the delegations tree key is present in storage.
181func (s *govStakerStore) HasDelegationsStoreKey() bool {
182	return s.kvStore.Has(StoreKeyDelegations)
183}
184
185// SetDelegations replaces the persisted delegation tree.
186//
187// Parameters:
188//   - _: Internal call discriminator; pass 0.
189//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
190//   - delegations: BPTree containing delegation records keyed by decimal delegation ID.
191//
192// Returns:
193//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
194func (s *govStakerStore) SetDelegations(_ int, rlm realm, delegations *bptree.BPTree) error {
195	if !rlm.IsCurrent() {
196		return errors.New(ErrSpoofedRealm)
197	}
198
199	return s.kvStore.Set(0, rlm, StoreKeyDelegations, delegations)
200}
201
202// HasDelegation reports whether a delegation with id exists.
203//
204// Parameters:
205//   - id: Numeric delegation identifier converted to the tree's decimal-string key.
206//
207// Returns:
208//   - bool: true when a delegation record exists for id, false when the key is absent.
209func (s *govStakerStore) HasDelegation(id int64) bool {
210	delegations := s.GetAllDelegations()
211	return delegations.Get(utils.Int64ToString(id)) != nil
212}
213
214// GetDelegation retrieves a delegation by id.
215//
216// Parameters:
217//   - id: Numeric delegation identifier converted to the tree's decimal-string key.
218//
219// Returns:
220//   - *Delegation: stored delegation, or nil when no record exists for id.
221//   - bool: true when a delegation was found; false when id is absent.
222func (s *govStakerStore) GetDelegation(id int64) (*Delegation, bool) {
223	delegations := s.GetAllDelegations()
224
225	result := delegations.Get(utils.Int64ToString(id))
226	if result == nil {
227		return nil, false
228	}
229
230	delegation, ok := result.(*Delegation)
231	if !ok {
232		panic(ufmt.Sprintf("failed to cast result to *Delegation: %T", result))
233	}
234
235	return delegation, true
236}
237
238// SetDelegation stores one delegation under id.
239//
240// Parameters:
241//   - _: Internal call discriminator; pass 0.
242//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
243//   - id: Numeric identifier used as the delegation's decimal-string tree key.
244//   - delegation: Delegation record to store for id.
245//
246// Returns:
247//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
248func (s *govStakerStore) SetDelegation(_ int, rlm realm, id int64, delegation *Delegation) error {
249	if !rlm.IsCurrent() {
250		return errors.New(ErrSpoofedRealm)
251	}
252
253	delegations := s.GetAllDelegations()
254
255	delegations.Set(utils.Int64ToString(id), delegation)
256	return s.kvStore.Set(0, rlm, StoreKeyDelegations, delegations)
257}
258
259// RemoveDelegation deletes the delegation stored under id.
260//
261// Parameters:
262//   - _: Internal call discriminator; pass 0.
263//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
264//   - id: Numeric delegation identifier whose decimal-string tree entry is removed.
265//
266// Returns:
267//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
268func (s *govStakerStore) RemoveDelegation(_ int, rlm realm, id int64) error {
269	if !rlm.IsCurrent() {
270		return errors.New(ErrSpoofedRealm)
271	}
272
273	delegations := s.GetAllDelegations()
274
275	delegations.Remove(utils.Int64ToString(id))
276	return s.kvStore.Set(0, rlm, StoreKeyDelegations, delegations)
277}
278
279// GetAllDelegations returns the persisted tree of delegation records keyed by decimal ID.
280//
281// Returns:
282//   - *bptree.BPTree: delegation tree; panics if storage is unavailable or contains a different type.
283func (s *govStakerStore) GetAllDelegations() *bptree.BPTree {
284	result, err := s.kvStore.Get(StoreKeyDelegations)
285	if err != nil {
286		panic(err)
287	}
288
289	delegations, ok := result.(*bptree.BPTree)
290	if !ok {
291		panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
292	}
293
294	return delegations
295}
296
297// Returns:
298//   - bool: true when the next-delegation-ID counter key is present in storage.
299func (s *govStakerStore) HasDelegationCounterStoreKey() bool {
300	return s.kvStore.Has(StoreKeyDelegationNextID)
301}
302
303// GetDelegationCounter returns the counter used to allocate delegation IDs.
304//
305// Returns:
306//   - *Counter: persisted next-ID counter; panics if storage is unavailable or contains a different type.
307func (s *govStakerStore) GetDelegationCounter() *Counter {
308	result, err := s.kvStore.Get(StoreKeyDelegationNextID)
309	if err != nil {
310		panic(err)
311	}
312
313	counter, ok := result.(*Counter)
314	if !ok {
315		panic(ufmt.Sprintf("failed to cast result to Counter: %T", result))
316	}
317
318	return counter
319}
320
321// SetDelegationCounter stores the counter used to allocate delegation IDs.
322//
323// Parameters:
324//   - _: Internal call discriminator; pass 0.
325//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
326//   - counter: Counter holding the next delegation ID.
327//
328// Returns:
329//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
330func (s *govStakerStore) SetDelegationCounter(_ int, rlm realm, counter *Counter) error {
331	if !rlm.IsCurrent() {
332		return errors.New(ErrSpoofedRealm)
333	}
334
335	return s.kvStore.Set(0, rlm, StoreKeyDelegationNextID, counter)
336}
337
338// Total delegation history methods (timestamp -> int64)
339// Returns:
340//   - bool: true when the total delegation-history key is present in storage.
341func (s *govStakerStore) HasTotalDelegationHistoryStoreKey() bool {
342	return s.kvStore.Has(StoreKeyTotalDelegationHistory)
343}
344
345// GetTotalDelegationHistory returns timestamp-indexed aggregate delegation history.
346//
347// Returns:
348//   - *UintTree: history mapping Unix timestamps to cumulative delegated amounts; panics on missing or invalid storage.
349func (s *govStakerStore) GetTotalDelegationHistory() *UintTree {
350	result, err := s.kvStore.Get(StoreKeyTotalDelegationHistory)
351	if err != nil {
352		panic(err)
353	}
354
355	history, ok := result.(*UintTree)
356	if !ok {
357		panic(ufmt.Sprintf("failed to cast result to *UintTree: %T", result))
358	}
359
360	return history
361}
362
363// SetTotalDelegationHistory stores timestamp-indexed aggregate delegation history.
364//
365// Parameters:
366//   - _: Internal call discriminator; pass 0.
367//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
368//   - history: UintTree mapping timestamps to cumulative total delegated amounts.
369//
370// Returns:
371//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
372func (s *govStakerStore) SetTotalDelegationHistory(_ int, rlm realm, history *UintTree) error {
373	if !rlm.IsCurrent() {
374		return errors.New(ErrSpoofedRealm)
375	}
376
377	return s.kvStore.Set(0, rlm, StoreKeyTotalDelegationHistory, history)
378}
379
380// User delegation history methods (address -> *UintTree[timestamp -> int64])
381// Returns:
382//   - bool: true when the per-user delegation-history key is present in storage.
383func (s *govStakerStore) HasUserDelegationHistoryStoreKey() bool {
384	return s.kvStore.Has(StoreKeyUserDelegationHistory)
385}
386
387// GetUserDelegationHistory returns the address-indexed delegation-history tree.
388//
389// Returns:
390//   - *bptree.BPTree: tree mapping delegator addresses to timestamp histories; panics on missing or invalid storage.
391func (s *govStakerStore) GetUserDelegationHistory() *bptree.BPTree {
392	result, err := s.kvStore.Get(StoreKeyUserDelegationHistory)
393	if err != nil {
394		panic(err)
395	}
396
397	history, ok := result.(*bptree.BPTree)
398	if !ok {
399		panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
400	}
401
402	return history
403}
404
405// SetUserDelegationHistory stores the address-indexed delegation-history tree.
406//
407// Parameters:
408//   - _: Internal call discriminator; pass 0.
409//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
410//   - history: BPTree mapping delegator addresses to their timestamp-indexed histories.
411//
412// Returns:
413//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
414func (s *govStakerStore) SetUserDelegationHistory(_ int, rlm realm, history *bptree.BPTree) error {
415	if !rlm.IsCurrent() {
416		return errors.New(ErrSpoofedRealm)
417	}
418
419	return s.kvStore.Set(0, rlm, StoreKeyUserDelegationHistory, history)
420}
421
422// Returns:
423//   - bool: true when the emission-reward-manager key is present in storage.
424func (s *govStakerStore) HasEmissionRewardManagerStoreKey() bool {
425	return s.kvStore.Has(StoreKeyEmissionRewardManager)
426}
427
428// GetEmissionRewardManager returns the persisted emission reward manager.
429//
430// Returns:
431//   - *EmissionRewardManager: emission reward accounting state; panics on missing or invalid storage.
432func (s *govStakerStore) GetEmissionRewardManager() *EmissionRewardManager {
433	result, err := s.kvStore.Get(StoreKeyEmissionRewardManager)
434	if err != nil {
435		panic(err)
436	}
437
438	manager, ok := result.(*EmissionRewardManager)
439	if !ok {
440		panic(ufmt.Sprintf("failed to cast result to *EmissionRewardManager: %T", result))
441	}
442
443	return manager
444}
445
446// SetEmissionRewardManager stores the emission reward manager.
447//
448// Parameters:
449//   - _: Internal call discriminator; pass 0.
450//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
451//   - manager: Emission reward accounting state to persist.
452//
453// Returns:
454//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
455func (s *govStakerStore) SetEmissionRewardManager(_ int, rlm realm, manager *EmissionRewardManager) error {
456	if !rlm.IsCurrent() {
457		return errors.New(ErrSpoofedRealm)
458	}
459
460	return s.kvStore.Set(0, rlm, StoreKeyEmissionRewardManager, manager)
461}
462
463// Returns:
464//   - bool: true when the protocol-fee reward-manager key is present in storage.
465func (s *govStakerStore) HasProtocolFeeRewardManagerStoreKey() bool {
466	return s.kvStore.Has(StoreKeyProtocolFeeRewardManager)
467}
468
469// GetProtocolFeeRewardManager returns the persisted protocol-fee reward manager.
470//
471// Returns:
472//   - *ProtocolFeeRewardManager: protocol-fee reward accounting state; panics on missing or invalid storage.
473func (s *govStakerStore) GetProtocolFeeRewardManager() *ProtocolFeeRewardManager {
474	result, err := s.kvStore.Get(StoreKeyProtocolFeeRewardManager)
475	if err != nil {
476		panic(err)
477	}
478
479	manager, ok := result.(*ProtocolFeeRewardManager)
480	if !ok {
481		panic(ufmt.Sprintf("failed to cast result to *ProtocolFeeRewardManager: %T", result))
482	}
483
484	return manager
485}
486
487// SetProtocolFeeRewardManager stores the protocol-fee reward manager.
488//
489// Parameters:
490//   - _: Internal call discriminator; pass 0.
491//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
492//   - manager: Protocol-fee reward accounting state to persist.
493//
494// Returns:
495//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
496func (s *govStakerStore) SetProtocolFeeRewardManager(_ int, rlm realm, manager *ProtocolFeeRewardManager) error {
497	if !rlm.IsCurrent() {
498		return errors.New(ErrSpoofedRealm)
499	}
500
501	return s.kvStore.Set(0, rlm, StoreKeyProtocolFeeRewardManager, manager)
502}
503
504// Returns:
505//   - bool: true when the delegation-manager key is present in storage.
506func (s *govStakerStore) HasDelegationManagerStoreKey() bool {
507	return s.kvStore.Has(StoreKeyDelegationManager)
508}
509
510// GetDelegationManager returns the persisted delegation manager.
511//
512// Returns:
513//   - *DelegationManager: delegation-management state; panics on missing or invalid storage.
514func (s *govStakerStore) GetDelegationManager() *DelegationManager {
515	result, err := s.kvStore.Get(StoreKeyDelegationManager)
516	if err != nil {
517		panic(err)
518	}
519
520	manager, ok := result.(*DelegationManager)
521	if !ok {
522		panic(ufmt.Sprintf("failed to cast result to *DelegationManager: %T", result))
523	}
524
525	return manager
526}
527
528// SetDelegationManager stores the delegation manager.
529//
530// Parameters:
531//   - _: Internal call discriminator; pass 0.
532//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
533//   - manager: Delegation-management state to persist.
534//
535// Returns:
536//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
537func (s *govStakerStore) SetDelegationManager(_ int, rlm realm, manager *DelegationManager) error {
538	if !rlm.IsCurrent() {
539		return errors.New(ErrSpoofedRealm)
540	}
541
542	return s.kvStore.Set(0, rlm, StoreKeyDelegationManager, manager)
543}
544
545// Returns:
546//   - bool: true when the launchpad-project-deposits key is present in storage.
547func (s *govStakerStore) HasLaunchpadProjectDepositsStoreKey() bool {
548	return s.kvStore.Has(StoreKeyLaunchpadProjectDeposits)
549}
550
551// GetLaunchpadProjectDeposits returns persisted launchpad project deposit state.
552//
553// Returns:
554//   - *LaunchpadProjectDeposits: launchpad deposit accounting state; panics on missing or invalid storage.
555func (s *govStakerStore) GetLaunchpadProjectDeposits() *LaunchpadProjectDeposits {
556	result, err := s.kvStore.Get(StoreKeyLaunchpadProjectDeposits)
557	if err != nil {
558		panic(err)
559	}
560
561	deposits, ok := result.(*LaunchpadProjectDeposits)
562	if !ok {
563		panic(ufmt.Sprintf("failed to cast result to *LaunchpadProjectDeposits: %T", result))
564	}
565
566	return deposits
567}
568
569// SetLaunchpadProjectDeposits stores launchpad project deposit state.
570//
571// Parameters:
572//   - _: Internal call discriminator; pass 0.
573//   - rlm: Propagated realm context; the write is accepted only when this realm is current.
574//   - deposits: Launchpad project deposit accounting state to persist.
575//
576// Returns:
577//   - error: nil on success; ErrSpoofedRealm when rlm is not current, or the underlying KV-store error.
578func (s *govStakerStore) SetLaunchpadProjectDeposits(_ int, rlm realm, deposits *LaunchpadProjectDeposits) error {
579	if !rlm.IsCurrent() {
580		return errors.New(ErrSpoofedRealm)
581	}
582
583	return s.kvStore.Set(0, rlm, StoreKeyLaunchpadProjectDeposits, deposits)
584}