code.vegaprotocol.io/vega@v0.79.0/core/coreapi/services/validators.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package services 17 18 import ( 19 "context" 20 "sync" 21 22 "code.vegaprotocol.io/vega/core/events" 23 "code.vegaprotocol.io/vega/core/subscribers" 24 eventspb "code.vegaprotocol.io/vega/protos/vega/events/v1" 25 ) 26 27 type validatorUpdateE interface { 28 events.Event 29 ValidatorUpdate() eventspb.ValidatorUpdate 30 } 31 32 type ethereumKeyRotationE interface { 33 events.Event 34 EthereumKeyRotation() eventspb.EthereumKeyRotation 35 } 36 type keyRotationE interface { 37 events.Event 38 KeyRotation() eventspb.KeyRotation 39 } 40 41 type Validators struct { 42 *subscribers.Base 43 ctx context.Context 44 45 mu sync.RWMutex 46 validators map[string]eventspb.ValidatorUpdate 47 ch chan events.Event 48 } 49 50 func NewValidators(ctx context.Context) (assets *Validators) { 51 defer func() { go assets.consume() }() 52 return &Validators{ 53 Base: subscribers.NewBase(ctx, 1000, true), 54 ctx: ctx, 55 validators: map[string]eventspb.ValidatorUpdate{}, 56 ch: make(chan events.Event, 100), 57 } 58 } 59 60 func (a *Validators) consume() { 61 defer func() { close(a.ch) }() 62 for { 63 select { 64 case <-a.Closed(): 65 return 66 case e, ok := <-a.ch: 67 if !ok { 68 // cleanup base 69 a.Halt() 70 // channel is closed 71 return 72 } 73 a.mu.Lock() 74 switch te := e.(type) { 75 case keyRotationE: 76 kr := te.KeyRotation() 77 vu, ok := a.validators[kr.NodeId] 78 if !ok { 79 break 80 } 81 82 vu.VegaPubKey = kr.NewPubKey 83 a.validators[kr.NodeId] = vu 84 case ethereumKeyRotationE: 85 kr := te.EthereumKeyRotation() 86 vu, ok := a.validators[kr.NodeId] 87 if !ok { 88 break 89 } 90 91 vu.EthereumAddress = kr.NewAddress 92 a.validators[kr.NodeId] = vu 93 case validatorUpdateE: 94 a.validators[te.ValidatorUpdate().NodeId] = te.ValidatorUpdate() 95 } 96 a.mu.Unlock() 97 } 98 } 99 } 100 101 func (a *Validators) Push(evts ...events.Event) { 102 for _, e := range evts { 103 switch te := e.(type) { 104 case keyRotationE, 105 ethereumKeyRotationE, 106 validatorUpdateE: 107 a.ch <- te 108 } 109 } 110 } 111 112 func (a *Validators) List() []*eventspb.ValidatorUpdate { 113 a.mu.RLock() 114 defer a.mu.RUnlock() 115 out := make([]*eventspb.ValidatorUpdate, 0, len(a.validators)) 116 for _, v := range a.validators { 117 v := v 118 out = append(out, &v) 119 } 120 return out 121 } 122 123 func (a *Validators) Types() []events.Type { 124 return []events.Type{ 125 events.ValidatorUpdateEvent, 126 events.EthereumKeyRotationEvent, 127 events.KeyRotationEvent, 128 } 129 }