store.gno
11.21 Kb · 332 lines
1package launchpad
2
3import (
4 "errors"
5 "strconv"
6
7 "gno.land/p/gnoswap/store/v1"
8 bptree "gno.land/p/nt/bptree/v0"
9 ufmt "gno.land/p/nt/ufmt/v0"
10)
11
12// NewBPTreeN allocates a BP-tree under /r/gnoswap/launchpad's realm context
13// (the realm that declares Project/Deposit/RewardManager). The tree's PkgID is
14// therefore /r/gnoswap/launchpad, matching the domain values it stores, so
15// tree.Set leaf-slot writes clear the readonly-taint gate regardless of which
16// realm (launchpad/v1, mock, tests) calls Set. Implementations, mocks, and
17// tests must allocate launchpad trees through here rather than calling
18// bptree.NewBPTreeN directly in their own realm.
19//
20// Parameters:
21// - fanout: branching factor passed to the BP-tree constructor.
22//
23// Returns:
24// - tree: new BP-tree allocated under the launchpad realm's package context.
25func NewBPTreeN(fanout int) *bptree.BPTree {
26 return bptree.NewBPTreeN(fanout)
27}
28
29type StoreKey string
30
31// String returns the textual key represented by this StoreKey.
32//
33// Returns:
34// - key: store key string used by the KV store.
35func (s StoreKey) String() string {
36 return string(s)
37}
38
39const (
40 StoreKeyProjects StoreKey = "projects" // Projects tree
41 StoreKeyProjectRecipients StoreKey = "projectRecipients" // Recipient membership tree
42 StoreKeyProjectTierRewardManagers StoreKey = "projectTierRewardManagers" // Project tier reward managers tree
43 StoreKeyDepositCounter StoreKey = "depositCounter" // Deposit counter
44 StoreKeyDeposits StoreKey = "deposits" // Deposits tree
45 StoreKeyTotalGNSStakedAmount StoreKey = "totalGNSStakedAmount" // Total active launchpad GNS stake
46)
47
48type launchpadStore struct {
49 kvStore store.KVStore
50}
51
52// HasProjectsKey checks if the projects key exists in the store.
53//
54// Returns:
55// - exists: true when the projects tree key is present in the KV store.
56func (s *launchpadStore) HasProjectsKey() bool {
57 return s.kvStore.Has(StoreKeyProjects.String())
58}
59
60// GetProjects retrieves the projects tree.
61//
62// Returns:
63// - projects: stored projects BP-tree keyed by project ID; the method panics if the key is missing or has the wrong type.
64func (s *launchpadStore) GetProjects() *bptree.BPTree {
65 result, err := s.kvStore.Get(StoreKeyProjects.String())
66 if err != nil {
67 panic(err)
68 }
69
70 projects, ok := result.(*bptree.BPTree)
71 if !ok {
72 panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
73 }
74
75 return projects
76}
77
78// SetProjects stores the projects tree.
79//
80// Parameters:
81// - _: cross-call discriminator; callers pass 0.
82// - rlm: propagated realm context; it must be current (`rlm.IsCurrent()`), otherwise the write returns ErrSpoofedRealm.
83// - projects: projects BP-tree to persist under the projects store key.
84//
85// Returns:
86// - err: nil when the tree is stored; non-nil for a spoofed realm or an underlying KV-store write failure.
87func (s *launchpadStore) SetProjects(_ int, rlm realm, projects *bptree.BPTree) error {
88 if !rlm.IsCurrent() {
89 return errors.New(ErrSpoofedRealm)
90 }
91
92 return s.kvStore.Set(0, rlm, StoreKeyProjects.String(), projects)
93}
94
95// HasProjectRecipientsKey checks if the recipient membership tree exists.
96//
97// Returns:
98// - exists: true when the project-recipient membership key is present in the KV store.
99func (s *launchpadStore) HasProjectRecipientsKey() bool {
100 return s.kvStore.Has(StoreKeyProjectRecipients.String())
101}
102
103// GetProjectRecipients retrieves the recipient address membership tree.
104//
105// Returns:
106// - recipients: stored recipient-membership BP-tree keyed by address string; the method panics if the key is missing or has the wrong type.
107func (s *launchpadStore) GetProjectRecipients() *bptree.BPTree {
108 result, err := s.kvStore.Get(StoreKeyProjectRecipients.String())
109 if err != nil {
110 panic(err)
111 }
112
113 recipients, ok := result.(*bptree.BPTree)
114 if !ok {
115 panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
116 }
117
118 return recipients
119}
120
121// SetProjectRecipients stores the recipient membership tree.
122//
123// Parameters:
124// - _: cross-call discriminator; callers pass 0.
125// - rlm: propagated realm context; it must be current (`rlm.IsCurrent()`), otherwise the write returns ErrSpoofedRealm.
126// - recipients: recipient-membership BP-tree to persist.
127//
128// Returns:
129// - err: nil when the tree is stored; non-nil for a spoofed realm or an underlying KV-store write failure.
130func (s *launchpadStore) SetProjectRecipients(_ int, rlm realm, recipients *bptree.BPTree) error {
131 if !rlm.IsCurrent() {
132 return errors.New(ErrSpoofedRealm)
133 }
134
135 return s.kvStore.Set(0, rlm, StoreKeyProjectRecipients.String(), recipients)
136}
137
138// HasProjectTierRewardManagersKey checks if the project tier reward managers key exists in the store.
139//
140// Returns:
141// - exists: true when the project-tier reward-manager key is present in the KV store.
142func (s *launchpadStore) HasProjectTierRewardManagersKey() bool {
143 return s.kvStore.Has(StoreKeyProjectTierRewardManagers.String())
144}
145
146// GetProjectTierRewardManagers retrieves the project tier reward managers tree.
147//
148// Returns:
149// - managers: stored reward-manager BP-tree keyed by project-tier ID; the method panics if the key is missing or has the wrong type.
150func (s *launchpadStore) GetProjectTierRewardManagers() *bptree.BPTree {
151 result, err := s.kvStore.Get(StoreKeyProjectTierRewardManagers.String())
152 if err != nil {
153 panic(err)
154 }
155
156 managers, ok := result.(*bptree.BPTree)
157 if !ok {
158 panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
159 }
160
161 return managers
162}
163
164// SetProjectTierRewardManagers stores the project tier reward managers tree.
165//
166// Parameters:
167// - _: cross-call discriminator; callers pass 0.
168// - rlm: propagated realm context; it must be current (`rlm.IsCurrent()`), otherwise the write returns ErrSpoofedRealm.
169// - managers: project-tier reward-manager BP-tree to persist.
170//
171// Returns:
172// - err: nil when the tree is stored; non-nil for a spoofed realm or an underlying KV-store write failure.
173func (s *launchpadStore) SetProjectTierRewardManagers(_ int, rlm realm, managers *bptree.BPTree) error {
174 if !rlm.IsCurrent() {
175 return errors.New(ErrSpoofedRealm)
176 }
177
178 return s.kvStore.Set(0, rlm, StoreKeyProjectTierRewardManagers.String(), managers)
179}
180
181// HasDepositCounterStoreKey checks if the deposit counter key exists in the store.
182//
183// Returns:
184// - exists: true when the deposit-counter key is present in the KV store.
185func (s *launchpadStore) HasDepositCounterStoreKey() bool {
186 return s.kvStore.Has(StoreKeyDepositCounter.String())
187}
188
189// GetDepositCounter retrieves the deposit counter.
190//
191// Returns:
192// - counter: stored deposit counter; the method panics if the key is missing or has the wrong type.
193func (s *launchpadStore) GetDepositCounter() *Counter {
194 result, err := s.kvStore.Get(StoreKeyDepositCounter.String())
195 if err != nil {
196 panic(err)
197 }
198
199 counter, ok := result.(*Counter)
200 if !ok {
201 panic(ufmt.Sprintf("failed to cast result to Counter: %T", result))
202 }
203
204 return counter
205}
206
207// SetDepositCounter stores the deposit counter under its dedicated key.
208//
209// Parameters:
210// - _: cross-call discriminator; callers pass 0.
211// - rlm: propagated realm context; it must be current (`rlm.IsCurrent()`), otherwise the write returns ErrSpoofedRealm.
212// - counter: deposit counter to persist.
213//
214// Returns:
215// - err: nil when the counter is stored; non-nil for a spoofed realm or an underlying KV-store write failure.
216func (s *launchpadStore) SetDepositCounter(_ int, rlm realm, counter *Counter) error {
217 if !rlm.IsCurrent() {
218 return errors.New(ErrSpoofedRealm)
219 }
220
221 return s.kvStore.Set(0, rlm, StoreKeyDepositCounter.String(), counter)
222}
223
224// NextDepositID increments the stored deposit counter and formats the new value as a decimal ID.
225//
226// Returns:
227// - depositID: next monotonically increasing deposit ID as a decimal string; the counter is incremented before formatting.
228func (s *launchpadStore) NextDepositID() string {
229 counter := s.GetDepositCounter()
230
231 return strconv.FormatInt(counter.Next(), 10)
232}
233
234// HasDepositsKey checks if the deposits key exists in the store.
235//
236// Returns:
237// - exists: true when the deposits tree key is present in the KV store.
238func (s *launchpadStore) HasDepositsKey() bool {
239 return s.kvStore.Has(StoreKeyDeposits.String())
240}
241
242// GetDeposits retrieves the deposits tree.
243//
244// Returns:
245// - deposits: stored deposits BP-tree keyed by deposit ID; the method panics if the key is missing or has the wrong type.
246func (s *launchpadStore) GetDeposits() *bptree.BPTree {
247 result, err := s.kvStore.Get(StoreKeyDeposits.String())
248 if err != nil {
249 panic(err)
250 }
251
252 deposits, ok := result.(*bptree.BPTree)
253 if !ok {
254 panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
255 }
256
257 return deposits
258}
259
260// SetDeposits stores the deposits tree.
261//
262// Parameters:
263// - _: cross-call discriminator; callers pass 0.
264// - rlm: propagated realm context; it must be current (`rlm.IsCurrent()`), otherwise the write returns ErrSpoofedRealm.
265// - deposits: deposits BP-tree to persist.
266//
267// Returns:
268// - err: nil when the tree is stored; non-nil for a spoofed realm or an underlying KV-store write failure.
269func (s *launchpadStore) SetDeposits(_ int, rlm realm, deposits *bptree.BPTree) error {
270 if !rlm.IsCurrent() {
271 return errors.New(ErrSpoofedRealm)
272 }
273
274 return s.kvStore.Set(0, rlm, StoreKeyDeposits.String(), deposits)
275}
276
277// HasTotalGNSStakedAmountKey checks if the total active GNS stake key exists in the store.
278//
279// Returns:
280// - exists: true when the total-GNS-staked amount key is present in the KV store.
281func (s *launchpadStore) HasTotalGNSStakedAmountKey() bool {
282 return s.kvStore.Has(StoreKeyTotalGNSStakedAmount.String())
283}
284
285// GetTotalGNSStakedAmount retrieves the total active GNS amount tracked by the store.
286//
287// Returns:
288// - amount: total currently staked GNS in base units; the method panics if the key is missing or has the wrong type.
289func (s *launchpadStore) GetTotalGNSStakedAmount() int64 {
290 result, err := s.kvStore.Get(StoreKeyTotalGNSStakedAmount.String())
291 if err != nil {
292 panic(err)
293 }
294
295 amount, ok := result.(int64)
296 if !ok {
297 panic(ufmt.Sprintf("failed to cast result to int64: %T", result))
298 }
299
300 return amount
301}
302
303// SetTotalGNSStakedAmount stores the total active GNS amount.
304//
305// Parameters:
306// - _: cross-call discriminator; callers pass 0.
307// - rlm: propagated realm context; it must be current (`rlm.IsCurrent()`), otherwise the write returns ErrSpoofedRealm.
308// - amount: total currently staked GNS in base units.
309//
310// Returns:
311// - err: nil when the amount is stored; non-nil for a spoofed realm or an underlying KV-store write failure.
312func (s *launchpadStore) SetTotalGNSStakedAmount(_ int, rlm realm, amount int64) error {
313 if !rlm.IsCurrent() {
314 return errors.New(ErrSpoofedRealm)
315 }
316
317 return s.kvStore.Set(0, rlm, StoreKeyTotalGNSStakedAmount.String(), amount)
318}
319
320// NewLaunchpadStore creates a new launchpad store instance with the provided KV store.
321// This function is used by the upgrade system to create storage instances for each implementation.
322//
323// Parameters:
324// - kvStore: key-value store used to persist launchpad state.
325//
326// Returns:
327// - launchpadStore: storage implementation backed by kvStore.
328func NewLaunchpadStore(kvStore store.KVStore) ILaunchpadStore {
329 return &launchpadStore{
330 kvStore: kvStore,
331 }
332}