code.vegaprotocol.io/vega@v0.79.0/core/integration/stubs/topology_stub.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 stubs 17 18 import ( 19 "context" 20 "sort" 21 22 "code.vegaprotocol.io/vega/core/events" 23 "code.vegaprotocol.io/vega/core/types" 24 "code.vegaprotocol.io/vega/core/validators" 25 "code.vegaprotocol.io/vega/libs/num" 26 ) 27 28 type TopologyStub struct { 29 validators map[string]string 30 nodeID string 31 broker *BrokerStub 32 minDelegation num.Decimal 33 } 34 35 func NewTopologyStub(nodeID string, broker *BrokerStub) *TopologyStub { 36 return &TopologyStub{ 37 validators: map[string]string{}, 38 nodeID: nodeID, 39 broker: broker, 40 } 41 } 42 43 func (ts *TopologyStub) OnMinDelegationUpdated(_ context.Context, minDelegation num.Decimal) error { 44 ts.minDelegation = minDelegation 45 return nil 46 } 47 48 func (ts *TopologyStub) Len() int { 49 return len(ts.validators) 50 } 51 52 func (ts *TopologyStub) ValidatorPerformanceScore(nodeID string) num.Decimal { 53 return num.DecimalFromFloat(1) 54 } 55 56 func (ts *TopologyStub) SelfNodeID() string { 57 return ts.nodeID 58 } 59 60 func (ts *TopologyStub) SelfVegaPubKey() string { 61 return ts.nodeID 62 } 63 64 func (ts *TopologyStub) IsValidator() bool { 65 return true 66 } 67 68 func (ts *TopologyStub) IsValidatorVegaPubKey(pubKey string) bool { 69 return true 70 } 71 72 func (ts *TopologyStub) IsTendermintValidator(pubKey string) bool { 73 return true 74 } 75 76 func (ts *TopologyStub) IsValidatorNodeID(nodeID string) bool { 77 _, ok := ts.validators[nodeID] 78 return ok 79 } 80 81 func (ts *TopologyStub) RecalcValidatorSet(ctx context.Context, epochSeq string, delegationState []*types.ValidatorData, stakeScoreParams types.StakeScoreParams) []*types.PartyContributionScore { 82 return []*types.PartyContributionScore{} 83 } 84 85 func (ts *TopologyStub) AllNodeIDs() []string { 86 nodes := make([]string, 0, len(ts.validators)) 87 for n := range ts.validators { 88 nodes = append(nodes, n) 89 } 90 sort.Strings(nodes) 91 return nodes 92 } 93 94 func (ts *TopologyStub) AllVegaPubKeys() []string { 95 nodes := make([]string, 0, len(ts.validators)) 96 for _, pk := range ts.validators { 97 nodes = append(nodes, pk) 98 } 99 sort.Strings(nodes) 100 return nodes 101 } 102 103 func (ts *TopologyStub) Get(key string) *validators.ValidatorData { 104 if data, ok := ts.validators[key]; ok { 105 return &validators.ValidatorData{ 106 ID: key, 107 VegaPubKey: data, 108 } 109 } 110 111 return nil 112 } 113 114 func (ts *TopologyStub) AddValidator(node string, pubkey string) { 115 ts.validators[node] = pubkey 116 } 117 118 func (ts *TopologyStub) GetRewardsScores(ctx context.Context, epochSeq string, delegationState []*types.ValidatorData, stakeScoreParams types.StakeScoreParams) (*types.ScoreData, *types.ScoreData) { 119 tmScores := ts.calculateTMScores(delegationState, stakeScoreParams) 120 evts := make([]events.Event, 0, len(tmScores.NodeIDSlice)) 121 for _, nodeID := range tmScores.NodeIDSlice { 122 evts = append(evts, events.NewValidatorScore(ctx, nodeID, epochSeq, tmScores.ValScores[nodeID], tmScores.NormalisedScores[nodeID], tmScores.RawValScores[nodeID], tmScores.PerformanceScores[nodeID], tmScores.MultisigScores[nodeID], "tendermint")) 123 } 124 125 ts.broker.SendBatch(evts) 126 127 return tmScores, &types.ScoreData{} 128 } 129 130 // calculateTMScores returns the reward validator scores for the tendermint validatore. 131 func (ts *TopologyStub) calculateTMScores(delegationState []*types.ValidatorData, stakeScoreParams types.StakeScoreParams) *types.ScoreData { 132 tmScores := &types.ScoreData{} 133 validatorSet := make(map[string]struct{}, len(delegationState)) 134 tmScores.PerformanceScores = make(map[string]num.Decimal, len(delegationState)) 135 for _, ds := range delegationState { 136 validatorSet[ds.NodeID] = struct{}{} 137 if ds.SelfStake.ToDecimal().GreaterThanOrEqual(ts.minDelegation) { 138 tmScores.PerformanceScores[ds.NodeID] = num.DecimalFromFloat(1) 139 } else { 140 tmScores.PerformanceScores[ds.NodeID] = num.DecimalZero() 141 } 142 } 143 144 tmDelegation, tmTotalDelegation := validators.CalcDelegation(validatorSet, delegationState) 145 optStake := validators.GetOptimalStake(tmTotalDelegation, len(tmDelegation), stakeScoreParams) 146 tv := validators.CalcAntiWhalingScore(tmDelegation, tmTotalDelegation, optStake, stakeScoreParams) 147 148 tmScores.RawValScores = tv 149 tmScores.ValScores = make(map[string]num.Decimal, len(tv)) 150 for k, d := range tv { 151 tmScores.ValScores[k] = d.Mul(tmScores.PerformanceScores[k]) 152 } 153 154 // normalise the scores 155 tmScores.NormalisedScores = ts.normaliseScores(tmScores.ValScores) 156 157 // sort the list of tm validators 158 tmNodeIDs := make([]string, 0, len(tv)) 159 for k := range tv { 160 tmNodeIDs = append(tmNodeIDs, k) 161 } 162 163 sort.Strings(tmNodeIDs) 164 tmScores.NodeIDSlice = tmNodeIDs 165 return tmScores 166 } 167 168 func (ts *TopologyStub) normaliseScores(scores map[string]num.Decimal) map[string]num.Decimal { 169 totalScore := num.DecimalZero() 170 for _, v := range scores { 171 totalScore = totalScore.Add(v) 172 } 173 174 normScores := make(map[string]num.Decimal, len(scores)) 175 for n, s := range scores { 176 if totalScore.IsPositive() { 177 normScores[n] = s.Div(totalScore) 178 } else { 179 normScores[n] = num.DecimalZero() 180 } 181 } 182 return normScores 183 } 184 185 func (*TopologyStub) GetVotingPower(pubkey string) int64 { 186 return 1 187 } 188 189 func (*TopologyStub) GetTotalVotingPower() int64 { 190 return 1 191 }