store.gno
6.54 Kb · 217 lines
1package position
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
12type StoreKey string
13
14// String returns the textual storage-key value.
15//
16// Returns:
17// - key: storage key represented as a string
18func (s StoreKey) String() string {
19 return string(s)
20}
21
22const (
23 StoreKeyPositions StoreKey = "positions" // Positions
24 StoreKeyPositionNextID StoreKey = "positionNextID" // Position next ID
25)
26
27type positionStore struct {
28 kvStore store.KVStore
29}
30
31// HasPositionsStoreKey reports whether the positions tree is present in the KV store.
32//
33// Returns:
34// - exists: true when the positions storage key is present
35func (s *positionStore) HasPositionsStoreKey() bool {
36 return s.kvStore.Has(StoreKeyPositions.String())
37}
38
39// GetPositions loads the stored tree containing all positions.
40//
41// Returns:
42// - positions: mutable positions tree keyed by decimal position ID; panics when the key is missing or has an unexpected type
43func (s *positionStore) GetPositions() *bptree.BPTree {
44 result, err := s.kvStore.Get(StoreKeyPositions.String())
45 if err != nil {
46 panic(err)
47 }
48
49 positions, ok := result.(*bptree.BPTree)
50 if !ok {
51 panic(ufmt.Sprintf("failed to cast result to *bptree.BPTree: %T", result))
52 }
53
54 return positions
55}
56
57// SetPositions stores the positions tree after validating the realm context.
58//
59// Parameters:
60// - _: leading integer discriminator; callers pass 0
61// - rlm: propagated realm context; the store requires it to be the current realm
62// - positions: positions tree to persist under the positions storage key
63//
64// Returns:
65// - err: nil when the tree is stored; non-nil when rlm is spoofed or the KV write fails
66func (s *positionStore) SetPositions(_ int, rlm realm, positions *bptree.BPTree) error {
67 if !rlm.IsCurrent() {
68 return errors.New(ErrSpoofedRealm)
69 }
70
71 return s.kvStore.Set(0, rlm, StoreKeyPositions.String(), positions)
72}
73
74// HasPositionNextIDStoreKey reports whether the next-position-ID value is present in the KV store.
75//
76// Returns:
77// - exists: true when the next-position-ID storage key is present
78func (s *positionStore) HasPositionNextIDStoreKey() bool {
79 return s.kvStore.Has(StoreKeyPositionNextID.String())
80}
81
82// GetPositionNextID loads the next position NFT ID to allocate.
83//
84// Returns:
85// - nextID: next position ID stored by the position manager; panics when the key is missing or has an unexpected type
86func (s *positionStore) GetPositionNextID() uint64 {
87 result, err := s.kvStore.Get(StoreKeyPositionNextID.String())
88 if err != nil {
89 panic(err)
90 }
91
92 nextID, ok := result.(uint64)
93 if !ok {
94 panic(ufmt.Sprintf("failed to cast result to uint64: %T", result))
95 }
96
97 return nextID
98}
99
100// SetPositionNextID stores the next position NFT ID after validating the realm context.
101//
102// Parameters:
103// - _: leading integer discriminator; callers pass 0
104// - rlm: propagated realm context; the store requires it to be the current realm
105// - nextID: next position ID to persist for the next mint
106//
107// Returns:
108// - err: nil when nextID is stored; non-nil when rlm is spoofed or the KV write fails
109func (s *positionStore) SetPositionNextID(_ int, rlm realm, nextID uint64) error {
110 if !rlm.IsCurrent() {
111 return errors.New(ErrSpoofedRealm)
112 }
113
114 return s.kvStore.Set(0, rlm, StoreKeyPositionNextID.String(), nextID)
115}
116
117// HasPosition reports whether a position is stored for the supplied NFT ID.
118//
119// Parameters:
120// - positionId: position NFT token ID to look up
121//
122// Returns:
123// - exists: true when the decimal positionId key exists in the positions tree
124func (s *positionStore) HasPosition(positionId uint64) bool {
125 positions := s.GetPositions()
126
127 return positions.Has(utils.Uint64ToString(positionId))
128}
129
130// GetPosition loads a position by NFT ID.
131//
132// Parameters:
133// - positionId: position NFT token ID to look up
134//
135// Returns:
136// - position: stored position value when present, or the zero Position when absent
137// - exists: true when positionId is present; false when no position is stored for that ID
138func (s *positionStore) GetPosition(positionId uint64) (Position, bool) {
139 positions := s.GetPositions()
140
141 result := positions.Get(utils.Uint64ToString(positionId))
142 if result == nil {
143 return Position{}, false
144 }
145
146 position, ok := result.(Position)
147 if !ok {
148 panic(ufmt.Sprintf("failed to cast result to Position: %T", result))
149 }
150
151 return position, true
152}
153
154// SetPosition inserts or replaces a position after validating the realm context.
155//
156// Parameters:
157// - _: leading integer discriminator; callers pass 0
158// - rlm: propagated realm context; the store requires it to be the current realm
159// - positionId: position NFT token ID used as the tree key
160// - position: position value to persist
161//
162// Returns:
163// - err: nil when the position is stored; non-nil when rlm is spoofed, the positions key is missing, or the KV write fails
164func (s *positionStore) SetPosition(_ int, rlm realm, positionId uint64, position Position) error {
165 if !rlm.IsCurrent() {
166 return errors.New(ErrSpoofedRealm)
167 }
168
169 if !s.HasPositionsStoreKey() {
170 return errors.New("positions store key not found")
171 }
172
173 positions := s.GetPositions()
174
175 positions.Set(utils.Uint64ToString(positionId), position)
176
177 return s.kvStore.Set(0, rlm, StoreKeyPositions.String(), positions)
178}
179
180// RemovePosition deletes a position after validating the realm context.
181//
182// Parameters:
183// - _: leading integer discriminator; callers pass 0
184// - rlm: propagated realm context; the store requires it to be the current realm
185// - positionId: position NFT token ID to remove from the positions tree
186//
187// Returns:
188// - err: nil when the position is removed and the tree is stored; non-nil when rlm is spoofed, the positions key is missing, or the KV write fails
189func (s *positionStore) RemovePosition(_ int, rlm realm, positionId uint64) error {
190 if !rlm.IsCurrent() {
191 return errors.New(ErrSpoofedRealm)
192 }
193
194 if !s.HasPositionsStoreKey() {
195 return errors.New("positions store key not found")
196 }
197
198 positions := s.GetPositions()
199
200 positions.Remove(utils.Uint64ToString(positionId))
201
202 return s.kvStore.Set(0, rlm, StoreKeyPositions.String(), positions)
203}
204
205// NewPositionStore creates a position store backed by the provided KV store.
206// The upgrade system uses it to construct storage instances for each implementation.
207//
208// Parameters:
209// - kvStore: Domain-owned KV store shared by position implementations.
210//
211// Returns:
212// - IPositionStore: Position storage wrapper backed by the supplied store.
213func NewPositionStore(kvStore store.KVStore) IPositionStore {
214 return &positionStore{
215 kvStore: kvStore,
216 }
217}