github.com/MetalBlockchain/metalgo@v1.11.9/snow/networking/tracker/targeter.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package tracker 5 6 import ( 7 "go.uber.org/zap" 8 9 "github.com/MetalBlockchain/metalgo/ids" 10 "github.com/MetalBlockchain/metalgo/snow/validators" 11 "github.com/MetalBlockchain/metalgo/utils/constants" 12 "github.com/MetalBlockchain/metalgo/utils/logging" 13 ) 14 15 var _ Targeter = (*targeter)(nil) 16 17 type Targeter interface { 18 // Returns the target usage of the given node. 19 TargetUsage(nodeID ids.NodeID) float64 20 } 21 22 type TargeterConfig struct { 23 // VdrAlloc is the amount of the resource to split over validators, weighted 24 // by stake. 25 VdrAlloc float64 `json:"vdrAlloc"` 26 27 // MaxNonVdrUsage is the amount of the resource which, if utilized, will 28 // result in allocations being based only on the stake weighted allocation. 29 MaxNonVdrUsage float64 `json:"maxNonVdrUsage"` 30 31 // MaxNonVdrNodeUsage is the amount of the resource to allocate to a node 32 // before adding the stake weighted allocation. 33 MaxNonVdrNodeUsage float64 `json:"maxNonVdrNodeUsage"` 34 } 35 36 func NewTargeter( 37 logger logging.Logger, 38 config *TargeterConfig, 39 vdrs validators.Manager, 40 tracker Tracker, 41 ) Targeter { 42 return &targeter{ 43 log: logger, 44 vdrs: vdrs, 45 tracker: tracker, 46 vdrAlloc: config.VdrAlloc, 47 maxNonVdrUsage: config.MaxNonVdrUsage, 48 maxNonVdrNodeUsage: config.MaxNonVdrNodeUsage, 49 } 50 } 51 52 type targeter struct { 53 vdrs validators.Manager 54 log logging.Logger 55 tracker Tracker 56 vdrAlloc float64 57 maxNonVdrUsage float64 58 maxNonVdrNodeUsage float64 59 } 60 61 func (t *targeter) TargetUsage(nodeID ids.NodeID) float64 { 62 // This node's at-large allocation is min([remaining at large], [max at large for a given peer]) 63 usage := t.tracker.TotalUsage() 64 baseAlloc := max(0, t.maxNonVdrUsage-usage) 65 baseAlloc = min(baseAlloc, t.maxNonVdrNodeUsage) 66 67 // This node gets a stake-weighted portion of the validator allocation. 68 weight := t.vdrs.GetWeight(constants.PrimaryNetworkID, nodeID) 69 if weight == 0 { 70 return baseAlloc 71 } 72 73 totalWeight, err := t.vdrs.TotalWeight(constants.PrimaryNetworkID) 74 if err != nil { 75 t.log.Error("couldn't get total weight of primary network", 76 zap.Error(err), 77 ) 78 return baseAlloc 79 } 80 81 vdrAlloc := t.vdrAlloc * float64(weight) / float64(totalWeight) 82 return vdrAlloc + baseAlloc 83 }