-
Notifications
You must be signed in to change notification settings - Fork 600
/
intermediary_account.go
159 lines (132 loc) · 5.58 KB
/
intermediary_account.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
package keeper
import (
"github.com/gogo/protobuf/proto"
lockuptypes "github.com/osmosis-labs/osmosis/v11/x/lockup/types"
"github.com/osmosis-labs/osmosis/v11/x/superfluid/types"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
func (k Keeper) GetAllIntermediaryAccounts(ctx sdk.Context) []types.SuperfluidIntermediaryAccount {
store := ctx.KVStore(k.storeKey)
prefixStore := prefix.NewStore(store, types.KeyPrefixIntermediaryAccount)
accounts := []types.SuperfluidIntermediaryAccount{}
iterator := sdk.KVStorePrefixIterator(prefixStore, nil)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
account := types.SuperfluidIntermediaryAccount{}
err := proto.Unmarshal(iterator.Value(), &account)
if err != nil {
panic(err)
}
accounts = append(accounts, account)
}
return accounts
}
func (k Keeper) GetIntermediaryAccount(ctx sdk.Context, address sdk.AccAddress) types.SuperfluidIntermediaryAccount {
store := ctx.KVStore(k.storeKey)
prefixStore := prefix.NewStore(store, types.KeyPrefixIntermediaryAccount)
acc := types.SuperfluidIntermediaryAccount{}
if address == nil {
return acc
}
bz := prefixStore.Get(address)
if bz == nil {
return acc
}
err := proto.Unmarshal(bz, &acc)
if err != nil {
panic(err)
}
return acc
}
func (k Keeper) GetIntermediaryAccountsForVal(ctx sdk.Context, valAddr sdk.ValAddress) []types.SuperfluidIntermediaryAccount {
accs := k.GetAllIntermediaryAccounts(ctx)
valAccs := []types.SuperfluidIntermediaryAccount{}
for _, acc := range accs {
if acc.ValAddr != valAddr.String() { // only apply for slashed validator
continue
}
valAccs = append(valAccs, acc)
}
return valAccs
}
func (k Keeper) GetOrCreateIntermediaryAccount(ctx sdk.Context, denom, valAddr string) (types.SuperfluidIntermediaryAccount, error) {
accountAddr := types.GetSuperfluidIntermediaryAccountAddr(denom, valAddr)
storeAccount := k.GetIntermediaryAccount(ctx, accountAddr)
// if storeAccount is in state, we return it.
if !storeAccount.Empty() {
return storeAccount, nil
}
// Otherwise we create the intermediary account.
// first step, we create the gaugeID
gaugeID, err := k.ik.CreateGauge(ctx, true, accountAddr, sdk.Coins{}, lockuptypes.QueryCondition{
LockQueryType: lockuptypes.ByDuration,
// move this synthetic denom creation to a dedicated function
Denom: stakingSyntheticDenom(denom, valAddr),
Duration: k.sk.GetParams(ctx).UnbondingTime,
}, ctx.BlockTime(), 1)
if err != nil {
k.Logger(ctx).Error(err.Error())
return types.SuperfluidIntermediaryAccount{}, err
}
intermediaryAcct := types.NewSuperfluidIntermediaryAccount(denom, valAddr, gaugeID)
k.SetIntermediaryAccount(ctx, intermediaryAcct)
// If the intermediary account's address doesn't already have an auth account associated with it,
// create a new account. We use base accounts, as this is whats done for cosmwasm smart contract accounts.
// and in the off-chance someone manages to find a bug that forces the account's creation.
if !k.ak.HasAccount(ctx, intermediaryAcct.GetAccAddress()) {
k.ak.SetAccount(ctx, authtypes.NewBaseAccount(intermediaryAcct.GetAccAddress(), nil, 0, 0))
}
return intermediaryAcct, nil
}
func (k Keeper) SetIntermediaryAccount(ctx sdk.Context, acc types.SuperfluidIntermediaryAccount) {
store := ctx.KVStore(k.storeKey)
prefixStore := prefix.NewStore(store, types.KeyPrefixIntermediaryAccount)
bz, err := proto.Marshal(&acc)
if err != nil {
panic(err)
}
prefixStore.Set(acc.GetAccAddress(), bz)
}
func (k Keeper) DeleteIntermediaryAccount(ctx sdk.Context, address sdk.AccAddress) {
store := ctx.KVStore(k.storeKey)
prefixStore := prefix.NewStore(store, types.KeyPrefixIntermediaryAccount)
prefixStore.Delete(address)
}
func (k Keeper) SetLockIdIntermediaryAccountConnection(ctx sdk.Context, lockId uint64, acc types.SuperfluidIntermediaryAccount) {
store := ctx.KVStore(k.storeKey)
prefixStore := prefix.NewStore(store, types.KeyPrefixLockIntermediaryAccAddr)
prefixStore.Set(sdk.Uint64ToBigEndian(lockId), acc.GetAccAddress())
}
func (k Keeper) GetLockIdIntermediaryAccountConnection(ctx sdk.Context, lockId uint64) sdk.AccAddress {
store := ctx.KVStore(k.storeKey)
prefixStore := prefix.NewStore(store, types.KeyPrefixLockIntermediaryAccAddr)
return prefixStore.Get(sdk.Uint64ToBigEndian(lockId))
}
func (k Keeper) GetAllLockIdIntermediaryAccountConnections(ctx sdk.Context) []types.LockIdIntermediaryAccountConnection {
store := ctx.KVStore(k.storeKey)
prefixStore := prefix.NewStore(store, types.KeyPrefixLockIntermediaryAccAddr)
iterator := prefixStore.Iterator(nil, nil)
connections := []types.LockIdIntermediaryAccountConnection{}
for ; iterator.Valid(); iterator.Next() {
connections = append(connections, types.LockIdIntermediaryAccountConnection{
LockId: sdk.BigEndianToUint64(iterator.Key()),
IntermediaryAccount: sdk.AccAddress(iterator.Value()).String(),
})
}
return connections
}
// Returns Superfluid Intermediate Account and a bool if found / not found.
func (k Keeper) GetIntermediaryAccountFromLockId(ctx sdk.Context, lockId uint64) (types.SuperfluidIntermediaryAccount, bool) {
addr := k.GetLockIdIntermediaryAccountConnection(ctx, lockId)
if addr.Empty() {
return types.SuperfluidIntermediaryAccount{}, false
}
return k.GetIntermediaryAccount(ctx, addr), true
}
func (k Keeper) DeleteLockIdIntermediaryAccountConnection(ctx sdk.Context, lockId uint64) {
store := ctx.KVStore(k.storeKey)
prefixStore := prefix.NewStore(store, types.KeyPrefixLockIntermediaryAccAddr)
prefixStore.Delete(sdk.Uint64ToBigEndian(lockId))
}