-
Notifications
You must be signed in to change notification settings - Fork 92
/
validators_map.go
117 lines (95 loc) · 2.93 KB
/
validators_map.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
package validator
// TODO(nkryuchkov): remove old validator interface(s)
import (
"context"
"fmt"
"github.com/bloxapp/ssv/protocol/v1/blockchain/beacon"
"sync"
"github.com/bloxapp/ssv/protocol/v1/validator"
"github.com/bloxapp/ssv/storage/basedb"
"go.uber.org/zap"
)
// validatorIterator is the function used to iterate over existing validators
type validatorIterator func(validator.IValidator) error
// validatorsMap manages a collection of running validators
type validatorsMap struct {
logger *zap.Logger
ctx context.Context
db basedb.IDb
optsTemplate *validator.Options
lock sync.RWMutex
validatorsMap map[string]validator.IValidator
}
func newValidatorsMap(ctx context.Context, logger *zap.Logger, db basedb.IDb, optsTemplate *validator.Options) *validatorsMap {
vm := validatorsMap{
logger: logger.With(zap.String("component", "validatorsMap")),
ctx: ctx,
db: db,
lock: sync.RWMutex{},
validatorsMap: make(map[string]validator.IValidator),
optsTemplate: optsTemplate,
}
return &vm
}
// ForEach loops over validators
func (vm *validatorsMap) ForEach(iterator validatorIterator) error {
vm.lock.RLock()
defer vm.lock.RUnlock()
for _, val := range vm.validatorsMap {
if err := iterator(val); err != nil {
return err
}
}
return nil
}
// GetValidator returns a validator
func (vm *validatorsMap) GetValidator(pubKey string) (validator.IValidator, bool) {
// main lock
vm.lock.RLock()
defer vm.lock.RUnlock()
v, ok := vm.validatorsMap[pubKey]
return v, ok
}
// GetOrCreateValidator creates a new validator instance if not exist
func (vm *validatorsMap) GetOrCreateValidator(share *beacon.Share) validator.IValidator {
// main lock
vm.lock.Lock()
defer vm.lock.Unlock()
pubKey := share.PublicKey.SerializeToHexStr()
if v, ok := vm.validatorsMap[pubKey]; !ok {
opts := *vm.optsTemplate
opts.Share = share
vm.validatorsMap[pubKey] = validator.NewValidator(&opts)
printShare(share, vm.logger, "setup validator done")
opts.Share = nil
} else {
printShare(v.GetShare(), vm.logger, "get validator")
}
return vm.validatorsMap[pubKey]
}
// RemoveValidator removes a validator instance from the map
func (vm *validatorsMap) RemoveValidator(pubKey string) validator.IValidator {
if v, found := vm.GetValidator(pubKey); found {
vm.lock.Lock()
defer vm.lock.Unlock()
delete(vm.validatorsMap, pubKey)
return v
}
return nil
}
// Size returns the number of validators in the map
func (vm *validatorsMap) Size() int {
vm.lock.RLock()
defer vm.lock.RUnlock()
return len(vm.validatorsMap)
}
func printShare(s *beacon.Share, logger *zap.Logger, msg string) {
var committee []string
for _, c := range s.Committee {
committee = append(committee, fmt.Sprintf(`[IbftId=%d, PK=%x]`, c.IbftID, c.Pk))
}
logger.Debug(msg,
zap.String("pubKey", s.PublicKey.SerializeToHexStr()),
zap.Uint64("nodeID", uint64(s.NodeID)),
zap.Strings("committee", committee))
}