forked from babylonlabs-io/babylon
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathepoch_val_set.go
145 lines (128 loc) · 4.87 KB
/
epoch_val_set.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
package keeper
import (
"context"
errorsmod "cosmossdk.io/errors"
sdkmath "cosmossdk.io/math"
"cosmossdk.io/store/prefix"
"github.com/babylonlabs-io/babylon/x/epoching/types"
"github.com/cosmos/cosmos-sdk/runtime"
sdk "github.com/cosmos/cosmos-sdk/types"
)
// GetValidatorSet returns the set of validators of a given epoch, where the validators are ordered by their address in ascending order
func (k Keeper) GetValidatorSet(ctx context.Context, epochNumber uint64) types.ValidatorSet {
vals := []types.Validator{}
store := k.valSetStore(ctx, epochNumber)
iterator := store.Iterator(nil, nil)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
addr := sdk.ValAddress(iterator.Key())
powerBytes := iterator.Value()
var power sdkmath.Int
if err := power.Unmarshal(powerBytes); err != nil {
panic(errorsmod.Wrap(types.ErrUnmarshal, err.Error()))
}
val := types.Validator{
Addr: addr,
Power: power.Int64(),
}
vals = append(vals, val)
}
return types.NewSortedValidatorSet(vals)
}
func (k Keeper) GetCurrentValidatorSet(ctx context.Context) types.ValidatorSet {
epochNumber := k.GetEpoch(ctx).EpochNumber
return k.GetValidatorSet(ctx, epochNumber)
}
// InitValidatorSet stores the validator set in the beginning of the current epoch
// This is called upon BeginBlock
func (k Keeper) InitValidatorSet(ctx context.Context) {
epochNumber := k.GetEpoch(ctx).EpochNumber
store := k.valSetStore(ctx, epochNumber)
totalPower := int64(0)
// store the validator set
err := k.stk.IterateLastValidatorPowers(ctx, func(addr sdk.ValAddress, power int64) (stop bool) {
addrBytes := []byte(addr)
powerBytes, err := sdkmath.NewInt(power).Marshal()
if err != nil {
panic(errorsmod.Wrap(types.ErrMarshal, err.Error()))
}
store.Set(addrBytes, powerBytes)
totalPower += power
return false
})
if err != nil {
panic(err)
}
// store total voting power of this validator set
epochNumberBytes := sdk.Uint64ToBigEndian(epochNumber)
totalPowerBytes, err := sdkmath.NewInt(totalPower).Marshal()
if err != nil {
panic(errorsmod.Wrap(types.ErrMarshal, err.Error()))
}
k.votingPowerStore(ctx).Set(epochNumberBytes, totalPowerBytes)
}
// ClearValidatorSet removes the validator set of a given epoch
// TODO: This is called upon the epoch is checkpointed
func (k Keeper) ClearValidatorSet(ctx context.Context, epochNumber uint64) {
store := k.valSetStore(ctx, epochNumber)
iterator := store.Iterator(nil, nil)
defer iterator.Close()
// clear the validator set
for ; iterator.Valid(); iterator.Next() {
key := iterator.Key()
store.Delete(key)
}
// clear total voting power of this validator set
powerStore := k.votingPowerStore(ctx)
epochNumberBytes := sdk.Uint64ToBigEndian(epochNumber)
powerStore.Delete(epochNumberBytes)
}
// GetValidatorVotingPower returns the voting power of a given validator in a given epoch
func (k Keeper) GetValidatorVotingPower(ctx context.Context, epochNumber uint64, valAddr sdk.ValAddress) (int64, error) {
store := k.valSetStore(ctx, epochNumber)
powerBytes := store.Get(valAddr)
if powerBytes == nil {
return 0, types.ErrUnknownValidator
}
var power sdkmath.Int
if err := power.Unmarshal(powerBytes); err != nil {
panic(errorsmod.Wrap(types.ErrUnmarshal, err.Error()))
}
return power.Int64(), nil
}
func (k Keeper) GetCurrentValidatorVotingPower(ctx context.Context, valAddr sdk.ValAddress) (int64, error) {
epochNumber := k.GetEpoch(ctx).EpochNumber
return k.GetValidatorVotingPower(ctx, epochNumber, valAddr)
}
// GetTotalVotingPower returns the total voting power of a given epoch
func (k Keeper) GetTotalVotingPower(ctx context.Context, epochNumber uint64) int64 {
epochNumberBytes := sdk.Uint64ToBigEndian(epochNumber)
store := k.votingPowerStore(ctx)
powerBytes := store.Get(epochNumberBytes)
if powerBytes == nil {
panic(types.ErrUnknownTotalVotingPower)
}
var power sdkmath.Int
if err := power.Unmarshal(powerBytes); err != nil {
panic(errorsmod.Wrap(types.ErrUnmarshal, err.Error()))
}
return power.Int64()
}
// valSetStore returns the KVStore of the validator set of a given epoch
// prefix: ValidatorSetKey || epochNumber
// key: string(address)
// value: voting power (in int64 as per Cosmos SDK)
func (k Keeper) valSetStore(ctx context.Context, epochNumber uint64) prefix.Store {
storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
valSetStore := prefix.NewStore(storeAdapter, types.ValidatorSetKey)
epochNumberBytes := sdk.Uint64ToBigEndian(epochNumber)
return prefix.NewStore(valSetStore, epochNumberBytes)
}
// votingPowerStore returns the total voting power of the validator set of a given epoch
// prefix: ValidatorSetKey
// key: epochNumber
// value: total voting power (in int64 as per Cosmos SDK)
func (k Keeper) votingPowerStore(ctx context.Context) prefix.Store {
storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
return prefix.NewStore(storeAdapter, types.VotingPowerKey)
}