-
Notifications
You must be signed in to change notification settings - Fork 0
/
keeper.go
217 lines (179 loc) · 6.96 KB
/
keeper.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
package keeper
import (
"fmt"
"time"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
paramtypes "github.com/cosmos/cosmos-sdk/x/params/types"
"github.com/tendermint/tendermint/libs/log"
"github.com/incubus-network/fury/x/auction/types"
)
type Keeper struct {
storeKey storetypes.StoreKey
cdc codec.Codec
paramSubspace paramtypes.Subspace
bankKeeper types.BankKeeper
accountKeeper types.AccountKeeper
}
// NewKeeper returns a new auction keeper.
func NewKeeper(cdc codec.Codec, storeKey storetypes.StoreKey, paramstore paramtypes.Subspace,
bankKeeper types.BankKeeper, accountKeeper types.AccountKeeper,
) Keeper {
if !paramstore.HasKeyTable() {
paramstore = paramstore.WithKeyTable(types.ParamKeyTable())
}
return Keeper{
storeKey: storeKey,
cdc: cdc,
paramSubspace: paramstore,
accountKeeper: accountKeeper,
bankKeeper: bankKeeper,
}
}
// MustUnmarshalAuction attempts to decode and return an Auction object from
// raw encoded bytes. It panics on error.
func (k Keeper) MustUnmarshalAuction(bz []byte) types.Auction {
auction, err := k.UnmarshalAuction(bz)
if err != nil {
panic(fmt.Errorf("failed to decode auction: %w", err))
}
return auction
}
// MustMarshalAuction attempts to encode an Auction object and returns the
// raw encoded bytes. It panics on error.
func (k Keeper) MustMarshalAuction(auction types.Auction) []byte {
bz, err := k.MarshalAuction(auction)
if err != nil {
panic(fmt.Errorf("failed to encode auction: %w", err))
}
return bz
}
// MarshalAuction protobuf serializes an Auction interface
func (k Keeper) MarshalAuction(auctionI types.Auction) ([]byte, error) {
return k.cdc.MarshalInterface(auctionI)
}
// UnmarshalAuction returns an Auction interface from raw encoded auction
// bytes of a Proto-based Auction type
func (k Keeper) UnmarshalAuction(bz []byte) (types.Auction, error) {
var evi types.Auction
return evi, k.cdc.UnmarshalInterface(bz, &evi)
}
// Logger returns a module-specific logger.
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
}
// SetNextAuctionID stores an ID to be used for the next created auction
func (k Keeper) SetNextAuctionID(ctx sdk.Context, id uint64) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.NextAuctionIDKey)
store.Set(types.NextAuctionIDKey, types.Uint64ToBytes(id))
}
// GetNextAuctionID reads the next available global ID from store
func (k Keeper) GetNextAuctionID(ctx sdk.Context) (uint64, error) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.NextAuctionIDKey)
bz := store.Get(types.NextAuctionIDKey)
if bz == nil {
return 0, types.ErrInvalidInitialAuctionID
}
return types.Uint64FromBytes(bz), nil
}
// IncrementNextAuctionID increments the next auction ID in the store by 1.
func (k Keeper) IncrementNextAuctionID(ctx sdk.Context) error {
id, err := k.GetNextAuctionID(ctx)
if err != nil {
return err
}
k.SetNextAuctionID(ctx, id+1)
return nil
}
// StoreNewAuction stores an auction, adding a new ID
func (k Keeper) StoreNewAuction(ctx sdk.Context, auction types.Auction) (uint64, error) {
newAuctionID, err := k.GetNextAuctionID(ctx)
if err != nil {
return 0, err
}
auction = auction.WithID(newAuctionID)
k.SetAuction(ctx, auction)
err = k.IncrementNextAuctionID(ctx)
if err != nil {
return 0, err
}
return newAuctionID, nil
}
// SetAuction puts the auction into the store, and updates any indexes.
func (k Keeper) SetAuction(ctx sdk.Context, auction types.Auction) {
// remove the auction from the byTime index if it is already in there
existingAuction, found := k.GetAuction(ctx, auction.GetID())
if found {
k.removeFromByTimeIndex(ctx, existingAuction.GetEndTime(), existingAuction.GetID())
}
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionKeyPrefix)
store.Set(types.GetAuctionKey(auction.GetID()), k.MustMarshalAuction(auction))
k.InsertIntoByTimeIndex(ctx, auction.GetEndTime(), auction.GetID())
}
// GetAuction gets an auction from the store.
func (k Keeper) GetAuction(ctx sdk.Context, auctionID uint64) (types.Auction, bool) {
var auction types.Auction
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionKeyPrefix)
bz := store.Get(types.GetAuctionKey(auctionID))
if bz == nil {
return auction, false
}
return k.MustUnmarshalAuction(bz), true
}
// DeleteAuction removes an auction from the store, and any indexes.
func (k Keeper) DeleteAuction(ctx sdk.Context, auctionID uint64) {
auction, found := k.GetAuction(ctx, auctionID)
if found {
k.removeFromByTimeIndex(ctx, auction.GetEndTime(), auctionID)
}
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionKeyPrefix)
store.Delete(types.GetAuctionKey(auctionID))
}
// InsertIntoByTimeIndex adds an auction ID and end time into the byTime index.
func (k Keeper) InsertIntoByTimeIndex(ctx sdk.Context, endTime time.Time, auctionID uint64) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionByTimeKeyPrefix)
store.Set(types.GetAuctionByTimeKey(endTime, auctionID), types.Uint64ToBytes(auctionID))
}
// removeFromByTimeIndex removes an auction ID and end time from the byTime index.
func (k Keeper) removeFromByTimeIndex(ctx sdk.Context, endTime time.Time, auctionID uint64) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionByTimeKeyPrefix)
store.Delete(types.GetAuctionByTimeKey(endTime, auctionID))
}
// IterateAuctionByTime provides an iterator over auctions ordered by auction.EndTime.
// For each auction cb will be callled. If cb returns true the iterator will close and stop.
func (k Keeper) IterateAuctionsByTime(ctx sdk.Context, inclusiveCutoffTime time.Time, cb func(auctionID uint64) (stop bool)) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AuctionByTimeKeyPrefix)
iterator := store.Iterator(
nil, // start at the very start of the prefix store
sdk.PrefixEndBytes(sdk.FormatTimeBytes(inclusiveCutoffTime)), // include any keys with times equal to inclusiveCutoffTime
)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
auctionID := types.Uint64FromBytes(iterator.Value())
if cb(auctionID) {
break
}
}
}
// IterateAuctions provides an iterator over all stored auctions.
// For each auction, cb will be called. If cb returns true, the iterator will close and stop.
func (k Keeper) IterateAuctions(ctx sdk.Context, cb func(auction types.Auction) (stop bool)) {
iterator := sdk.KVStorePrefixIterator(ctx.KVStore(k.storeKey), types.AuctionKeyPrefix)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
auction := k.MustUnmarshalAuction(iterator.Value())
if cb(auction) {
break
}
}
}
// GetAllAuctions returns all auctions from the store
func (k Keeper) GetAllAuctions(ctx sdk.Context) (auctions []types.Auction) {
k.IterateAuctions(ctx, func(auction types.Auction) bool {
auctions = append(auctions, auction)
return false
})
return
}