-
Notifications
You must be signed in to change notification settings - Fork 201
/
state.go
139 lines (116 loc) · 4.63 KB
/
state.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
package keeper
import (
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/NibiruChain/nibiru/x/incentivization/types"
)
const (
IncentivizationProgramStartID uint64 = 0
)
var (
incentivizationProgramNamespace = []byte{0x0}
incentivizationProgramIDNamespace = append(incentivizationProgramNamespace, 0x0)
incentivizationProgramIDKey = []byte{0x1}
incentivizationProgramObjectsNamespace = append(incentivizationProgramNamespace, 0x1)
incentivizationProgramDenomIndex = append(incentivizationProgramNamespace, 0x2)
incentivizationProgramDenomMap = append(incentivizationProgramNamespace, 0x3)
)
func (k Keeper) IncentivizationProgramsState(ctx sdk.Context) IncentivizationProgramState {
return newIncentivizationProgramState(ctx, k.storeKey, k.cdc)
}
func newIncentivizationProgramState(ctx sdk.Context, key sdk.StoreKey, cdc codec.Codec) IncentivizationProgramState {
store := ctx.KVStore(key)
return IncentivizationProgramState{
cdc: cdc,
ctx: ctx,
programID: prefix.NewStore(store, incentivizationProgramIDNamespace),
incentivizationPrograms: prefix.NewStore(store, incentivizationProgramObjectsNamespace),
denomToIncentivizationProgramIndex: prefix.NewStore(store, incentivizationProgramDenomIndex),
denomMap: prefix.NewStore(store, incentivizationProgramDenomMap),
}
}
type IncentivizationProgramState struct {
cdc codec.Codec
ctx sdk.Context
programID sdk.KVStore
incentivizationPrograms sdk.KVStore // maps objects
denomToIncentivizationProgramIndex sdk.KVStore // maps denom to incentivization program
denomMap sdk.KVStore // provides the current list of incentivized denomss through a map
}
// PeekNextID returns the next ID without actually increasing the counter.
func (s IncentivizationProgramState) PeekNextID() uint64 {
id := s.programID.Get(incentivizationProgramIDKey)
switch id {
case nil:
return 0
default:
return sdk.BigEndianToUint64(id)
}
}
func (s IncentivizationProgramState) Create(program *types.IncentivizationProgram) {
if program.Id != 0 {
panic("incentivization program id must not be set")
}
id := s.nextPrimaryKey()
pk := sdk.Uint64ToBigEndian(id) // TODO(mercilex): inefficient, doing this twice
program.Id = id
s.incentivizationPrograms.Set(pk, s.cdc.MustMarshal(program))
s.index(pk, program)
}
func (s IncentivizationProgramState) Get(id uint64) (*types.IncentivizationProgram, error) {
bytes := s.incentivizationPrograms.Get(sdk.Uint64ToBigEndian(id))
if bytes == nil {
return nil, types.ErrIncentivizationProgramNotFound.Wrapf("%d", id)
}
program := new(types.IncentivizationProgram)
s.cdc.MustUnmarshal(bytes, program)
return program, nil
}
func (s IncentivizationProgramState) index(pk []byte, program *types.IncentivizationProgram) {
s.denomMap.Set([]byte(program.LpDenom), []byte{})
s.denomToIncentivizationProgramIndex.Set(s.denomKey(program.LpDenom, pk), []byte{})
}
/*func (s IncentivizationProgramState) unindex(pk []byte, program *types.IncentivizationProgram) {
s.denomToIncentivizationProgramIndex.Delete(s.denomKey(program.LpDenom, pk))
// now we check if there are more lp denoms
iter := s.denomToIncentivizationProgramIndex.Iterator(s.denomKey(program.LpDenom, nil), nil)
defer iter.Close()
// in case the iter is not valid, it means that there are no more
// incentivization programs associated with the given denom.
// Hence we clear the denom map.
if !iter.Valid() {
s.denomMap.Delete([]byte(program.LpDenom))
}
}*/
func (s IncentivizationProgramState) nextPrimaryKey() uint64 {
idBytes := s.programID.Get(incentivizationProgramIDKey)
var id uint64
switch idBytes {
case nil:
id = IncentivizationProgramStartID
default:
id = sdk.BigEndianToUint64(idBytes)
}
s.programID.Set(incentivizationProgramIDKey, sdk.Uint64ToBigEndian(id+1))
return id
}
func (s IncentivizationProgramState) denomKey(denom string, pk []byte) []byte {
key := make([]byte, 0, len(denom)+1+len(pk))
key = append(key, []byte(denom)...)
key = append(key, 0xFF)
key = append(key, pk...)
return key
}
// IteratePrograms iterates over every program
func (s IncentivizationProgramState) IteratePrograms(do func(program *types.IncentivizationProgram) (stop bool)) {
iter := s.incentivizationPrograms.Iterator(nil, nil)
defer iter.Close()
for ; iter.Valid(); iter.Next() {
program := new(types.IncentivizationProgram)
s.cdc.MustUnmarshal(iter.Value(), program)
if do(program) {
break
}
}
}