/
iterator.go
223 lines (188 loc) · 10.4 KB
/
iterator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
package keeper
import (
"time"
db "github.com/tendermint/tm-db"
"github.com/osmosis-labs/osmosis/v10/x/lockup/types"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
func unlockingPrefix(isUnlocking bool) []byte {
if isUnlocking {
return types.KeyPrefixUnlocking
}
return types.KeyPrefixNotUnlocking
}
func (k Keeper) iteratorAfterTime(ctx sdk.Context, prefix []byte, time time.Time) sdk.Iterator {
store := ctx.KVStore(k.storeKey)
timeKey := getTimeKey(time)
key := combineKeys(prefix, timeKey)
// If it’s unlockTime, then it should count as unlocked
// inclusive end bytes = key + 1, next iterator
return store.Iterator(storetypes.PrefixEndBytes(key), storetypes.PrefixEndBytes(prefix))
}
// iterate through keys between that use prefix, and have a time LTE max time.
func (k Keeper) iteratorBeforeTime(ctx sdk.Context, prefix []byte, maxTime time.Time) sdk.Iterator {
store := ctx.KVStore(k.storeKey)
timeKey := getTimeKey(maxTime)
key := combineKeys(prefix, timeKey)
// If it’s unlockTime, then it should count as unlocked
// inclusive end bytes = key + 1, next iterator
return store.Iterator(prefix, storetypes.PrefixEndBytes(key))
}
func (k Keeper) iteratorDuration(ctx sdk.Context, prefix []byte, duration time.Duration) sdk.Iterator {
durationKey := getDurationKey(duration)
key := combineKeys(prefix, durationKey)
store := ctx.KVStore(k.storeKey)
return sdk.KVStorePrefixIterator(store, key)
}
func (k Keeper) iteratorLongerDuration(ctx sdk.Context, prefix []byte, duration time.Duration) sdk.Iterator {
store := ctx.KVStore(k.storeKey)
durationKey := getDurationKey(duration)
key := combineKeys(prefix, durationKey)
// inclusive on longer side, means >= (longer or equal)
return store.Iterator(key, storetypes.PrefixEndBytes(prefix))
}
func (k Keeper) iteratorShorterDuration(ctx sdk.Context, prefix []byte, duration time.Duration) sdk.Iterator {
store := ctx.KVStore(k.storeKey)
durationKey := getDurationKey(duration)
key := combineKeys(prefix, durationKey)
// inclusive on longer side, shorter means < (lower)
return store.Iterator(prefix, key)
}
func (k Keeper) iterator(ctx sdk.Context, prefix []byte) sdk.Iterator {
store := ctx.KVStore(k.storeKey)
return sdk.KVStorePrefixIterator(store, prefix)
}
// LockIteratorAfterTime returns the iterator to get locked coins.
func (k Keeper) LockIteratorAfterTime(ctx sdk.Context, time time.Time) sdk.Iterator {
unlockingPrefix := unlockingPrefix(true)
return k.iteratorAfterTime(ctx, combineKeys(unlockingPrefix, types.KeyPrefixLockTimestamp), time)
}
// LockIteratorBeforeTime returns the iterator to get unlockable coins.
func (k Keeper) LockIteratorBeforeTime(ctx sdk.Context, time time.Time) sdk.Iterator {
unlockingPrefix := unlockingPrefix(true)
return k.iteratorBeforeTime(ctx, combineKeys(unlockingPrefix, types.KeyPrefixLockTimestamp), time)
}
// LockIterator returns the iterator used for getting all locks.
func (k Keeper) LockIterator(ctx sdk.Context, isUnlocking bool) sdk.Iterator {
unlockingPrefix := unlockingPrefix(isUnlocking)
return k.iterator(ctx, combineKeys(unlockingPrefix, types.KeyPrefixLockDuration))
}
// LockIteratorAfterTimeDenom returns the iterator to get locked coins by denom.
func (k Keeper) LockIteratorAfterTimeDenom(ctx sdk.Context, denom string, time time.Time) sdk.Iterator {
unlockingPrefix := unlockingPrefix(true)
return k.iteratorAfterTime(ctx, combineKeys(unlockingPrefix, types.KeyPrefixDenomLockTimestamp, []byte(denom)), time)
}
// LockIteratorBeforeTimeDenom returns the iterator to get unlockable coins by denom.
func (k Keeper) LockIteratorBeforeTimeDenom(ctx sdk.Context, denom string, time time.Time) sdk.Iterator {
unlockingPrefix := unlockingPrefix(true)
return k.iteratorBeforeTime(ctx, combineKeys(unlockingPrefix, types.KeyPrefixDenomLockTimestamp, []byte(denom)), time)
}
// LockIteratorLongerThanDurationDenom returns the iterator to get locked locks by denom.
func (k Keeper) LockIteratorLongerThanDurationDenom(ctx sdk.Context, isUnlocking bool, denom string, duration time.Duration) sdk.Iterator {
unlockingPrefix := unlockingPrefix(isUnlocking)
return k.iteratorLongerDuration(ctx, combineKeys(unlockingPrefix, types.KeyPrefixDenomLockDuration, []byte(denom)), duration)
}
// LockIteratorDenom returns the iterator used for getting all locks by denom.
func (k Keeper) LockIteratorDenom(ctx sdk.Context, isUnlocking bool, denom string) sdk.Iterator {
unlockingPrefix := unlockingPrefix(isUnlocking)
return k.iterator(ctx, combineKeys(unlockingPrefix, types.KeyPrefixDenomLockDuration, []byte(denom)))
}
// AccountLockIteratorAfterTime returns the iterator to get locked coins by account.
func (k Keeper) AccountLockIteratorAfterTime(ctx sdk.Context, addr sdk.AccAddress, time time.Time) sdk.Iterator {
unlockingPrefix := unlockingPrefix(true)
return k.iteratorAfterTime(ctx, combineKeys(unlockingPrefix, types.KeyPrefixAccountLockTimestamp, addr), time)
}
// AccountLockIteratorBeforeTime returns the iterator to get unlockable coins by account.
func (k Keeper) AccountLockIteratorBeforeTime(ctx sdk.Context, addr sdk.AccAddress, time time.Time) sdk.Iterator {
unlockingPrefix := unlockingPrefix(true)
return k.iteratorBeforeTime(ctx, combineKeys(unlockingPrefix, types.KeyPrefixAccountLockTimestamp, addr), time)
}
// AccountLockIterator returns the iterator used for getting all locks by account.
func (k Keeper) AccountLockIterator(ctx sdk.Context, isUnlocking bool, addr sdk.AccAddress) sdk.Iterator {
unlockingPrefix := unlockingPrefix(isUnlocking)
return k.iterator(ctx, combineKeys(unlockingPrefix, types.KeyPrefixAccountLockDuration, addr))
}
// AccountLockIteratorAfterTimeDenom returns the iterator to get locked coins by account and denom.
func (k Keeper) AccountLockIteratorAfterTimeDenom(ctx sdk.Context, addr sdk.AccAddress, denom string, time time.Time) sdk.Iterator {
unlockingPrefix := unlockingPrefix(true)
return k.iteratorAfterTime(ctx, combineKeys(unlockingPrefix, types.KeyPrefixAccountDenomLockTimestamp, addr, []byte(denom)), time)
}
// AccountLockIteratorBeforeTimeDenom returns the iterator to get unlockable coins by account and denom.
func (k Keeper) AccountLockIteratorBeforeTimeDenom(ctx sdk.Context, addr sdk.AccAddress, denom string, time time.Time) sdk.Iterator {
unlockingPrefix := unlockingPrefix(true)
return k.iteratorBeforeTime(ctx, combineKeys(unlockingPrefix, types.KeyPrefixAccountDenomLockTimestamp, addr, []byte(denom)), time)
}
// AccountLockIteratorDenom returns the iterator used for getting all locks by account and denom.
func (k Keeper) AccountLockIteratorDenom(ctx sdk.Context, isUnlocking bool, addr sdk.AccAddress, denom string) sdk.Iterator {
unlockingPrefix := unlockingPrefix(isUnlocking)
return k.iterator(ctx, combineKeys(unlockingPrefix, types.KeyPrefixAccountDenomLockDuration, addr, []byte(denom)))
}
// AccountLockIteratorLongerDuration returns iterator used for getting all locks by account longer than duration.
func (k Keeper) AccountLockIteratorLongerDuration(ctx sdk.Context, isUnlocking bool, addr sdk.AccAddress, duration time.Duration) sdk.Iterator {
unlockingPrefix := unlockingPrefix(isUnlocking)
return k.iteratorLongerDuration(ctx, combineKeys(unlockingPrefix, types.KeyPrefixAccountLockDuration, addr), duration)
}
// AccountLockIteratorDuration returns an iterator used for getting all locks for a given account, isUnlocking, and specific duration.
func (k Keeper) AccountLockIteratorDuration(ctx sdk.Context, isUnlocking bool, addr sdk.AccAddress, duration time.Duration) sdk.Iterator {
unlockingPrefix := unlockingPrefix(isUnlocking)
return k.iteratorDuration(ctx, combineKeys(unlockingPrefix, types.KeyPrefixAccountLockDuration, addr), duration)
}
// AccountLockIteratorShorterThanDuration returns an iterator used for getting all locks by account shorter than the specified duration.
func (k Keeper) AccountLockIteratorShorterThanDuration(ctx sdk.Context, isUnlocking bool, addr sdk.AccAddress, duration time.Duration) sdk.Iterator {
unlockingPrefix := unlockingPrefix(isUnlocking)
return k.iteratorShorterDuration(ctx, combineKeys(unlockingPrefix, types.KeyPrefixAccountLockDuration, addr), duration)
}
// AccountLockIteratorLongerDurationDenom returns iterator used for getting all locks by account and denom longer than duration.
func (k Keeper) AccountLockIteratorLongerDurationDenom(ctx sdk.Context, isUnlocking bool, addr sdk.AccAddress, denom string, duration time.Duration) sdk.Iterator {
unlockingPrefix := unlockingPrefix(isUnlocking)
return k.iteratorLongerDuration(ctx, combineKeys(unlockingPrefix, types.KeyPrefixAccountDenomLockDuration, addr, []byte(denom)), duration)
}
// AccountLockIteratorDurationDenom returns iterator used for getting all locks by account and denom with specific duration.
func (k Keeper) AccountLockIteratorDurationDenom(ctx sdk.Context, isUnlocking bool, addr sdk.AccAddress, denom string, duration time.Duration) sdk.Iterator {
unlockingPrefix := unlockingPrefix(isUnlocking)
return k.iteratorDuration(ctx, combineKeys(unlockingPrefix, types.KeyPrefixAccountDenomLockDuration, addr, []byte(denom)), duration)
}
func (k Keeper) getLocksFromIterator(ctx sdk.Context, iterator db.Iterator) []types.PeriodLock {
locks := []types.PeriodLock{}
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
lockID := sdk.BigEndianToUint64(iterator.Value())
lock, err := k.GetLockByID(ctx, lockID)
if err != nil {
panic(err)
}
locks = append(locks, *lock)
}
return locks
}
func (k Keeper) unlockFromIterator(ctx sdk.Context, iterator db.Iterator) ([]types.PeriodLock, sdk.Coins) {
// Note: this function is only used for an account
// and this has no conflicts with synthetic lockups
coins := sdk.Coins{}
locks := k.getLocksFromIterator(ctx, iterator)
for _, lock := range locks {
err := k.UnlockMaturedLock(ctx, lock.ID)
if err != nil {
panic(err)
}
// sum up all coins unlocked
coins = coins.Add(lock.Coins...)
}
return locks, coins
}
func (k Keeper) beginUnlockFromIterator(ctx sdk.Context, iterator db.Iterator) ([]types.PeriodLock, error) {
// Note: this function is only used for an account
// and this has no conflicts with synthetic lockups
locks := k.getLocksFromIterator(ctx, iterator)
for _, lock := range locks {
err := k.BeginUnlock(ctx, lock.ID, nil)
if err != nil {
return locks, err
}
}
return locks, nil
}
func (k Keeper) getCoinsFromIterator(ctx sdk.Context, iterator db.Iterator) sdk.Coins {
return k.getCoinsFromLocks(k.getLocksFromIterator(ctx, iterator))
}