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