Search Apps Documentation Source Content File Folder Download Copy Actions Download 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}