/
indexHashedNodesCoordinatorWithRater.go
108 lines (89 loc) · 3.38 KB
/
indexHashedNodesCoordinatorWithRater.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
package nodesCoordinator
import (
"github.com/ElrondNetwork/elrond-go-core/core/check"
"github.com/ElrondNetwork/elrond-go/common"
"github.com/ElrondNetwork/elrond-go/state"
)
var _ NodesCoordinatorHelper = (*indexHashedNodesCoordinatorWithRater)(nil)
type indexHashedNodesCoordinatorWithRater struct {
*indexHashedNodesCoordinator
chanceComputer ChanceComputer
}
// NewIndexHashedNodesCoordinatorWithRater creates a new index hashed group selector
func NewIndexHashedNodesCoordinatorWithRater(
indexNodesCoordinator *indexHashedNodesCoordinator,
chanceComputer ChanceComputer,
) (*indexHashedNodesCoordinatorWithRater, error) {
if check.IfNil(indexNodesCoordinator) {
return nil, ErrNilNodesCoordinator
}
if check.IfNil(chanceComputer) {
return nil, ErrNilChanceComputer
}
ihncr := &indexHashedNodesCoordinatorWithRater{
indexHashedNodesCoordinator: indexNodesCoordinator,
chanceComputer: chanceComputer,
}
ihncr.nodesCoordinatorHelper = ihncr
ihncr.mutNodesConfig.Lock()
defer ihncr.mutNodesConfig.Unlock()
nodesConfig, ok := ihncr.nodesConfig[ihncr.currentEpoch]
if !ok {
nodesConfig = &epochNodesConfig{}
}
nodesConfig.mutNodesMaps.Lock()
defer nodesConfig.mutNodesMaps.Unlock()
var err error
nodesConfig.selectors, err = ihncr.createSelectors(nodesConfig)
if err != nil {
return nil, err
}
ihncr.epochStartRegistrationHandler.UnregisterHandler(indexNodesCoordinator)
ihncr.epochStartRegistrationHandler.RegisterHandler(ihncr)
return ihncr, nil
}
// ComputeAdditionalLeaving - computes the extra leaving validators that have a threshold below the minimum rating
func (ihnc *indexHashedNodesCoordinatorWithRater) ComputeAdditionalLeaving(allValidators []*state.ShardValidatorInfo) (map[uint32][]Validator, error) {
extraLeavingNodesMap := make(map[uint32][]Validator)
minChances := ihnc.GetChance(0)
for _, vInfo := range allValidators {
if vInfo.List == string(common.InactiveList) || vInfo.List == string(common.JailedList) {
continue
}
chances := ihnc.GetChance(vInfo.TempRating)
if chances < minChances {
val, err := NewValidator(vInfo.PublicKey, chances, vInfo.Index)
if err != nil {
return nil, err
}
log.Debug("computed leaving based on rating for validator", "pk", vInfo.GetPublicKey())
extraLeavingNodesMap[vInfo.ShardId] = append(extraLeavingNodesMap[vInfo.ShardId], val)
}
}
return extraLeavingNodesMap, nil
}
//IsInterfaceNil verifies that the underlying value is nil
func (ihnc *indexHashedNodesCoordinatorWithRater) IsInterfaceNil() bool {
return ihnc == nil
}
// GetChance returns the chance from an actual rating
func (ihnc *indexHashedNodesCoordinatorWithRater) GetChance(rating uint32) uint32 {
return ihnc.chanceComputer.GetChance(rating)
}
// ValidatorsWeights returns the weights/chances for each given validator
func (ihnc *indexHashedNodesCoordinatorWithRater) ValidatorsWeights(validators []Validator) ([]uint32, error) {
minChance := ihnc.GetChance(0)
weights := make([]uint32, len(validators))
for i, validatorInShard := range validators {
weights[i] = validatorInShard.Chances()
if weights[i] < minChance {
//default weight if all validators need to be selected
weights[i] = minChance
}
}
return weights, nil
}
// LoadState loads the nodes coordinator state from the used boot storage
func (ihnc *indexHashedNodesCoordinatorWithRater) LoadState(key []byte) error {
return ihnc.baseLoadState(key)
}