-
Notifications
You must be signed in to change notification settings - Fork 202
/
epoch_unbonding_record.go
157 lines (135 loc) · 6.23 KB
/
epoch_unbonding_record.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
package keeper
import (
"encoding/binary"
"fmt"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
errorsmod "cosmossdk.io/errors"
stakeibctypes "github.com/Stride-Labs/stride/v17/x/stakeibc/types"
"github.com/Stride-Labs/stride/v17/x/records/types"
)
// SetEpochUnbondingRecord set a specific epochUnbondingRecord in the store
func (k Keeper) SetEpochUnbondingRecord(ctx sdk.Context, epochUnbondingRecord types.EpochUnbondingRecord) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.EpochUnbondingRecordKey))
b := k.Cdc.MustMarshal(&epochUnbondingRecord)
store.Set(GetEpochUnbondingRecordIDBytes(epochUnbondingRecord.EpochNumber), b)
}
// GetEpochUnbondingRecord returns a epochUnbondingRecord from its id
func (k Keeper) GetEpochUnbondingRecord(ctx sdk.Context, epochNumber uint64) (val types.EpochUnbondingRecord, found bool) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.EpochUnbondingRecordKey))
b := store.Get(GetEpochUnbondingRecordIDBytes(epochNumber))
if b == nil {
return val, false
}
k.Cdc.MustUnmarshal(b, &val)
return val, true
}
// RemoveEpochUnbondingRecord removes a epochUnbondingRecord from the store
func (k Keeper) RemoveEpochUnbondingRecord(ctx sdk.Context, epochNumber uint64) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.EpochUnbondingRecordKey))
store.Delete(GetEpochUnbondingRecordIDBytes(epochNumber))
}
// GetAllEpochUnbondingRecord returns all epochUnbondingRecord
func (k Keeper) GetAllEpochUnbondingRecord(ctx sdk.Context) (list []types.EpochUnbondingRecord) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.EpochUnbondingRecordKey))
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var val types.EpochUnbondingRecord
k.Cdc.MustUnmarshal(iterator.Value(), &val)
list = append(list, val)
}
return
}
// GetAllPreviousEpochUnbondingRecords returns all epochUnbondingRecords prior to a given epoch
func (k Keeper) GetAllPreviousEpochUnbondingRecords(ctx sdk.Context, epochNumber uint64) (list []types.EpochUnbondingRecord) {
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefix(types.EpochUnbondingRecordKey))
iterator := sdk.KVStorePrefixIterator(store, []byte{})
defer iterator.Close()
// these aren't guaranteed to be ordered
for ; iterator.Valid(); iterator.Next() {
var val types.EpochUnbondingRecord
k.Cdc.MustUnmarshal(iterator.Value(), &val)
if val.EpochNumber < epochNumber {
list = append(list, val)
}
}
return
}
// GetEpochUnbondingRecordIDBytes returns the byte representation of the ID
func GetEpochUnbondingRecordIDBytes(id uint64) []byte {
bz := make([]byte, 8)
binary.BigEndian.PutUint64(bz, id)
return bz
}
// GetEpochUnbondingRecordIDFromBytes returns ID in uint64 format from a byte array
func GetEpochUnbondingRecordIDFromBytes(bz []byte) uint64 {
return binary.BigEndian.Uint64(bz)
}
// GetEpochUnbondingRecordByEpoch returns a epochUnbondingRecord from its epochNumber
func (k Keeper) GetHostZoneUnbondingByChainId(ctx sdk.Context, epochNumber uint64, chainId string) (val *types.HostZoneUnbonding, found bool) {
epochUnbondingRecord, found := k.GetEpochUnbondingRecord(ctx, epochNumber)
if !found {
return nil, false
}
hostZoneUnbondings := epochUnbondingRecord.HostZoneUnbondings
for _, hzUnbondingRecord := range hostZoneUnbondings {
if hzUnbondingRecord.HostZoneId == chainId {
return hzUnbondingRecord, true
}
}
return &types.HostZoneUnbonding{}, false
}
// Adds a HostZoneUnbonding to an EpochUnbondingRecord
// TODO [cleanup]: Return error instead of success
func (k Keeper) AddHostZoneToEpochUnbondingRecord(ctx sdk.Context, epochNumber uint64, chainId string, hzu *types.HostZoneUnbonding) (val *types.EpochUnbondingRecord, success bool) {
epochUnbondingRecord, found := k.GetEpochUnbondingRecord(ctx, epochNumber)
if !found {
return nil, false
}
wasSet := false
for i, hostZoneUnbonding := range epochUnbondingRecord.HostZoneUnbondings {
if hostZoneUnbonding.GetHostZoneId() == chainId {
epochUnbondingRecord.HostZoneUnbondings[i] = hzu
wasSet = true
break
}
}
if !wasSet {
// add new host zone unbonding record
epochUnbondingRecord.HostZoneUnbondings = append(epochUnbondingRecord.HostZoneUnbondings, hzu)
}
return &epochUnbondingRecord, true
}
// Stores a host zone unbonding record - set via an epoch unbonding record
func (k Keeper) SetHostZoneUnbondingRecord(ctx sdk.Context, epochNumber uint64, chainId string, hostZoneUnbonding types.HostZoneUnbonding) error {
epochUnbondingRecord, success := k.AddHostZoneToEpochUnbondingRecord(ctx, epochNumber, chainId, &hostZoneUnbonding)
if !success {
return errorsmod.Wrapf(types.ErrEpochUnbondingRecordNotFound, "epoch unbonding record not found for epoch %d", epochNumber)
}
k.SetEpochUnbondingRecord(ctx, *epochUnbondingRecord)
return nil
}
// Updates the status for a given host zone across relevant epoch unbonding record IDs
func (k Keeper) SetHostZoneUnbondingStatus(ctx sdk.Context, chainId string, epochUnbondingRecordIds []uint64, status types.HostZoneUnbonding_Status) error {
for _, epochUnbondingRecordId := range epochUnbondingRecordIds {
k.Logger(ctx).Info(fmt.Sprintf("Updating host zone unbondings on EpochUnbondingRecord %d to status %s", epochUnbondingRecordId, status.String()))
// fetch the host zone unbonding
hostZoneUnbonding, found := k.GetHostZoneUnbondingByChainId(ctx, epochUnbondingRecordId, chainId)
if !found {
errMsg := fmt.Sprintf("Error fetching host zone unbonding record for epoch: %d, host zone: %s", epochUnbondingRecordId, chainId)
k.Logger(ctx).Error(errMsg)
return errorsmod.Wrapf(stakeibctypes.ErrHostZoneNotFound, errMsg)
}
hostZoneUnbonding.Status = status
// save the updated hzu on the epoch unbonding record
updatedRecord, success := k.AddHostZoneToEpochUnbondingRecord(ctx, epochUnbondingRecordId, chainId, hostZoneUnbonding)
if !success {
errMsg := fmt.Sprintf("Error adding host zone unbonding record to epoch unbonding record: %d, host zone: %s", epochUnbondingRecordId, chainId)
k.Logger(ctx).Error(errMsg)
return errorsmod.Wrap(types.ErrAddingHostZone, errMsg)
}
k.SetEpochUnbondingRecord(ctx, *updatedRecord)
}
return nil
}