github.com/onflow/flow-go@v0.33.17/network/p2p/config/peer_scoring.go (about) 1 package p2pconfig 2 3 import "time" 4 5 const ( 6 PeerScoringKey = "peer-scoring" 7 InternalKey = "internal" 8 ProtocolKey = "protocol" 9 ) 10 11 // PeerScoringParameters encapsulates the parameters of the GossipSub scoring system. 12 type PeerScoringParameters struct { 13 // Internal is the internal parameters of the GossipSub scoring system that are hosted by 14 // the GossipSub system, and are not exposed to the Flow protocol. 15 // The internal parameters are hosted by the GossipSub system. 16 Internal InternalGossipSubScoreParams `validate:"required" mapstructure:"internal"` 17 // Protocol is the protocol parameters of the peer scoring system that is hosted by the Flow protocol. 18 Protocol ProtocolLevelGossipSubScoreParams `validate:"required" mapstructure:"protocol"` 19 } 20 21 const ( 22 AppSpecificScoreWeightKey = "app-specific-score-weight" 23 DecayToZeroKey = "decay-to-zero" 24 ThresholdsKey = "thresholds" 25 BehaviourKey = "behaviour" 26 TopicKey = "topic" 27 ) 28 29 type InternalGossipSubScoreParams struct { 30 // AppSpecificScoreWeight is the weight for app-specific scores. It is used to scale the app-specific 31 // scores to the same range as the other scores. At the current version, we don't distinguish between the app-specific 32 // scores and the other scores, so we set it to 1. 33 AppSpecificScoreWeight float64 `validate:"gt=0,lte=1" mapstructure:"app-specific-score-weight"` 34 // DecayInterval is the decay interval for the overall score of a peer at the GossipSub scoring 35 // system. We set it to 1 minute so that it is not too short so that a malicious node can recover from a penalty 36 // and is not too long so that a well-behaved node can't recover from a penalty. 37 DecayInterval time.Duration `validate:"gte=1m" mapstructure:"decay-interval"` 38 // DecayToZero is the decay to zero for the overall score of a peer at the GossipSub scoring system. 39 // It defines the maximum value below which a peer scoring counter is reset to zero. 40 // This is to prevent the counter from decaying to a very small value. 41 // The value is 0.01, which means that a counter will be reset to zero if it decays to 0.01. 42 // When a counter hits the DecayToZero threshold, it means that the peer did not exhibit the behavior 43 // for a long time, and we can reset the counter. 44 DecayToZero float64 `validate:"required" mapstructure:"decay-to-zero"` 45 TopicParameters TopicScoringParameters `validate:"required" mapstructure:"topic"` 46 Thresholds InternalScoringThresholds `validate:"required" mapstructure:"thresholds"` 47 Behaviour InternalScoringBehavioural `validate:"required" mapstructure:"behaviour"` 48 } 49 50 const ( 51 MaxDebugLogsKey = "max-debug-logs" 52 AppSpecificKey = "application-specific" 53 ) 54 55 type ProtocolLevelGossipSubScoreParams struct { 56 MaxDebugLogs uint32 `validate:"lte=50" mapstructure:"max-debug-logs"` 57 AppSpecificScore ApplicationSpecificScoreParameters `validate:"required" mapstructure:"application-specific"` 58 } 59 60 const ( 61 MaxAppSpecificKey = "max-app-specific" 62 MinAppSpecificKey = "min-app-specific" 63 UnknownIdentityKey = "unknown-identity" 64 InvalidSubscriptionKey = "invalid-subscription" 65 StakedIdentityKey = "staked-identity" 66 RewardKey = "reward" 67 PenaltyKey = "penalty" 68 ) 69 70 type ApplicationSpecificScoreParameters struct { 71 // MaxAppSpecificPenalty the maximum penalty for sever offenses that we apply to a remote node score. The score 72 // mechanism of GossipSub in Flow is designed in a way that all other infractions are penalized with a fraction of 73 // this value. We have also set the other parameters such as DefaultGraylistThreshold, DefaultGossipThreshold and DefaultPublishThreshold to 74 // be a bit higher than this, i.e., MaxAppSpecificPenalty + 1. This ensures that a node with a score of MaxAppSpecificPenalty 75 // will be graylisted (i.e., all incoming and outgoing RPCs are rejected) and will not be able to publish or gossip any messages. 76 MaxAppSpecificPenalty float64 `validate:"lt=0" mapstructure:"max-app-specific-penalty"` 77 // MinAppSpecificPenalty the minimum penalty for sever offenses that we apply to a remote node score. 78 MinAppSpecificPenalty float64 `validate:"lt=0" mapstructure:"min-app-specific-penalty"` 79 // UnknownIdentityPenalty is the penalty for unknown identity. It is applied to the peer's score when 80 // the peer is not in the identity list. 81 UnknownIdentityPenalty float64 `validate:"lt=0" mapstructure:"unknown-identity-penalty"` 82 // InvalidSubscriptionPenalty is the penalty for invalid subscription. It is applied to the peer's score when 83 // the peer subscribes to a topic that it is not authorized to subscribe to. 84 InvalidSubscriptionPenalty float64 `validate:"lt=0" mapstructure:"invalid-subscription-penalty"` 85 // MaxAppSpecificReward is the reward for well-behaving staked peers. If a peer does not have 86 // any misbehavior record, e.g., invalid subscription, invalid message, etc., it will be rewarded with this score. 87 MaxAppSpecificReward float64 `validate:"gt=0" mapstructure:"max-app-specific-reward"` 88 // StakedIdentityReward is the reward for staking peers. It is applied to the peer's score when 89 // the peer does not have any misbehavior record, e.g., invalid subscription, invalid message, etc. 90 // The purpose is to reward the staking peers for their contribution to the network and prioritize them in neighbor selection. 91 StakedIdentityReward float64 `validate:"gt=0" mapstructure:"staked-identity-reward"` 92 } 93 94 const ( 95 GossipThresholdKey = "gossip" 96 PublishThresholdKey = "publish" 97 GraylistThresholdKey = "graylist" 98 AcceptPXThresholdKey = "accept-px" 99 OpportunisticGraftThresholdKey = "opportunistic-graft" 100 ) 101 102 // InternalScoringThresholds score option threshold configuration parameters. 103 type InternalScoringThresholds struct { 104 // Gossip when a peer's penalty drops below this threshold, 105 // no gossip is emitted towards that peer and gossip from that peer is ignored. 106 Gossip float64 `validate:"lt=0" mapstructure:"gossip"` 107 // Publish when a peer's penalty drops below this threshold, 108 // self-published messages are not propagated towards this peer. 109 Publish float64 `validate:"lt=0" mapstructure:"publish"` 110 // Graylist when a peer's penalty drops below this threshold, the peer is graylisted, i.e., 111 // incoming RPCs from the peer are ignored. 112 Graylist float64 `validate:"lt=0" mapstructure:"graylist"` 113 // AcceptPX when a peer sends us PX information with a prune, we only accept it and connect to the supplied 114 // peers if the originating peer's penalty exceeds this threshold. 115 AcceptPX float64 `validate:"gt=0" mapstructure:"accept-px"` 116 // OpportunisticGraft when the median peer penalty in the mesh drops below this value, 117 // the peer may select more peers with penalty above the median to opportunistically graft on the mesh. 118 OpportunisticGraft float64 `validate:"gt=0" mapstructure:"opportunistic-graft"` 119 } 120 121 const ( 122 BehaviourPenaltyThresholdKey = "penalty-threshold" 123 BehaviourPenaltyWeightKey = "penalty-weight" 124 BehaviourPenaltyDecayKey = "penalty-decay" 125 ) 126 127 // InternalScoringBehavioural score option behaviour configuration parameters. 128 type InternalScoringBehavioural struct { 129 // PenaltyThreshold is the threshold when the behavior of a peer is considered as bad by GossipSub. 130 // Currently, the misbehavior is defined as advertising an iHave without responding to the iWants (iHave broken promises), as well as attempting 131 // on GRAFT when the peer is considered for a PRUNE backoff, i.e., the local peer does not allow the peer to join the local topic mesh 132 // for a while, and the remote peer keep attempting on GRAFT (aka GRAFT flood). 133 // When the misbehavior counter of a peer goes beyond this threshold, the peer is penalized by BehaviorPenaltyWeight (see below) for the excess misbehavior. 134 // 135 // An iHave broken promise means that a peer advertises an iHave for a message, but does not respond to the iWant requests for that message. 136 // For iHave broken promises, the gossipsub scoring works as follows: 137 // It samples ONLY A SINGLE iHave out of the entire RPC. 138 // If that iHave is not followed by an actual message within the next 3 seconds, the peer misbehavior counter is incremented by 1. 139 // 140 // The counter is also decayed by (0.99) every decay interval (DecayInterval) i.e., every minute. 141 // Note that misbehaviors are counted by GossipSub across all topics (and is different from the Application Layer Misbehaviors that we count through 142 // the ALSP system). 143 PenaltyThreshold float64 `validate:"gt=0" mapstructure:"penalty-threshold"` 144 // PenaltyWeight is the weight for applying penalty when a peer misbehavior goes beyond the threshold. 145 // Misbehavior of a peer at gossipsub layer is defined as advertising an iHave without responding to the iWants (broken promises), as well as attempting 146 // on GRAFT when the peer is considered for a PRUNE backoff, i.e., the local peer does not allow the peer to join the local topic mesh 147 // This is detected by the GossipSub scoring system, and the peer is penalized by BehaviorPenaltyWeight. 148 // 149 // An iHave broken promise means that a peer advertises an iHave for a message, but does not respond to the iWant requests for that message. 150 // For iHave broken promises, the gossipsub scoring works as follows: 151 // It samples ONLY A SINGLE iHave out of the entire RPC. 152 // If that iHave is not followed by an actual message within the next 3 seconds, the peer misbehavior counter is incremented by 1. 153 PenaltyWeight float64 `validate:"lt=0" mapstructure:"penalty-weight"` 154 // PenaltyDecay is the decay interval for the misbehavior counter of a peer. The misbehavior counter is 155 // incremented by GossipSub for iHave broken promises or the GRAFT flooding attacks (i.e., each GRAFT received from a remote peer while that peer is on a PRUNE backoff). 156 // 157 // An iHave broken promise means that a peer advertises an iHave for a message, but does not respond to the iWant requests for that message. 158 // For iHave broken promises, the gossipsub scoring works as follows: 159 // It samples ONLY A SINGLE iHave out of the entire RPC. 160 // If that iHave is not followed by an actual message within the next 3 seconds, the peer misbehavior counter is incremented by 1. 161 // This means that regardless of how many iHave broken promises an RPC contains, the misbehavior counter is incremented by 1. 162 // That is why we decay the misbehavior counter very slow, as this counter indicates a severe misbehavior. 163 // The misbehavior counter is decayed per decay interval (i.e., DecayInterval = 1 minute) by GossipSub. 164 // 165 // Note that misbehaviors are counted by GossipSub across all topics (and is different from the Application Layer Misbehaviors that we count through 166 // the ALSP system that is based on the engines report). 167 PenaltyDecay float64 `validate:"gt=0,lt=1" mapstructure:"penalty-decay"` 168 } 169 170 const ( 171 SkipAtomicValidationKey = "skip-atomic-validation" 172 InvalidMessageDeliveriesWeightKey = "invalid-message-deliveries-weight" 173 InvalidMessageDeliveriesDecayKey = "invalid-message-deliveries-decay" 174 TimeInMeshQuantumKey = "time-in-mesh-quantum" 175 TopicWeightKey = "topic-weight" 176 MeshMessageDeliveriesDecayKey = "mesh-message-deliveries-decay" 177 MeshMessageDeliveriesCapKey = "mesh-message-deliveries-cap" 178 MeshMessageDeliveryThresholdKey = "mesh-message-deliveries-threshold" 179 MeshDeliveriesWeightKey = "mesh-deliveries-weight" 180 MeshMessageDeliveriesWindowKey = "mesh-message-deliveries-window" 181 MeshMessageDeliveryActivationKey = "mesh-message-delivery-activation" 182 ) 183 184 // TopicScoringParameters score option topic validation configuration parameters. 185 type TopicScoringParameters struct { 186 // SkipAtomicValidation is the value for the skip atomic validation flag for topics. 187 // If set it to true, the gossipsub parameter validation will not fail if we leave some of the 188 // topic parameters at their values, i.e., zero. 189 SkipAtomicValidation bool `validate:"required" mapstructure:"skip-atomic-validation"` 190 // InvalidMessageDeliveriesWeight this value is applied to the square of the number of invalid message deliveries on a topic. 191 // It is used to penalize peers that send invalid messages. By an invalid message, we mean a message that is not signed by the 192 // publisher, or a message that is not signed by the peer that sent it. 193 InvalidMessageDeliveriesWeight float64 `validate:"lt=0" mapstructure:"invalid-message-deliveries-weight"` 194 // InvalidMessageDeliveriesDecay decay factor used to decay the number of invalid message deliveries. 195 // The total number of invalid message deliveries is multiplied by this factor at each heartbeat interval to 196 // decay the number of invalid message deliveries, and prevent the peer from being disconnected if it stops 197 // sending invalid messages. 198 InvalidMessageDeliveriesDecay float64 `validate:"gt=0,lt=1" mapstructure:"invalid-message-deliveries-decay"` 199 // TimeInMeshQuantum is the time in mesh quantum for the GossipSub scoring system. It is used to gauge 200 // a discrete time interval for the time in mesh counter. 201 TimeInMeshQuantum time.Duration `validate:"gte=1h" mapstructure:"time-in-mesh-quantum"` 202 // Weight is the weight of a topic in the GossipSub scoring system. 203 // The overall score of a peer in a topic mesh is multiplied by the weight of the topic when calculating the overall score of the peer. 204 TopicWeight float64 `validate:"gt=0" mapstructure:"topic-weight"` 205 // MeshMessageDeliveriesDecay is applied to the number of actual message deliveries in a topic mesh 206 // at each decay interval (i.e., DecayInterval). 207 // It is used to decay the number of actual message deliveries, and prevents past message 208 // deliveries from affecting the current score of the peer. 209 MeshMessageDeliveriesDecay float64 `validate:"gt=0" mapstructure:"mesh-message-deliveries-decay"` 210 // MeshMessageDeliveriesCap is the maximum number of actual message deliveries in a topic 211 // mesh that is used to calculate the score of a peer in that topic mesh. 212 MeshMessageDeliveriesCap float64 `validate:"gt=0" mapstructure:"mesh-message-deliveries-cap"` 213 // MeshMessageDeliveryThreshold is the threshold for the number of actual message deliveries in a 214 // topic mesh that is used to calculate the score of a peer in that topic mesh. 215 // If the number of actual message deliveries in a topic mesh is less than this value, 216 // the peer will be penalized by square of the difference between the actual message deliveries and the threshold, 217 // i.e., -w * (actual - threshold)^2 where `actual` and `threshold` are the actual message deliveries and the 218 // threshold, respectively, and `w` is the weight (i.e., MeshMessageDeliveriesWeight). 219 MeshMessageDeliveryThreshold float64 `validate:"gt=0" mapstructure:"mesh-message-deliveries-threshold"` 220 // MeshDeliveriesWeight is the weight for applying penalty when a peer is under-performing in a topic mesh. 221 // Upon every decay interval, if the number of actual message deliveries is less than the topic mesh message deliveries threshold 222 // (i.e., MeshMessageDeliveriesThreshold), the peer will be penalized by square of the difference between the actual 223 // message deliveries and the threshold, multiplied by this weight, i.e., -w * (actual - threshold)^2 where w is the weight, and 224 // `actual` and `threshold` are the actual message deliveries and the threshold, respectively. 225 MeshDeliveriesWeight float64 `validate:"lt=0" mapstructure:"mesh-deliveries-weight"` 226 // MeshMessageDeliveriesWindow is the window size is time interval that we count a delivery of an already 227 // seen message towards the score of a peer in a topic mesh. The delivery is counted 228 // by GossipSub only if the previous sender of the message is different from the current sender. 229 MeshMessageDeliveriesWindow time.Duration `validate:"gte=1m" mapstructure:"mesh-message-deliveries-window"` 230 // MeshMessageDeliveryActivation is the time interval that we wait for a new peer that joins a topic mesh 231 // till start counting the number of actual message deliveries of that peer in that topic mesh. 232 MeshMessageDeliveryActivation time.Duration `validate:"gte=2m" mapstructure:"mesh-message-delivery-activation"` 233 }