github.com/ethereum-optimism/optimism@v1.7.2/op-node/p2p/peer_params.go (about) 1 package p2p 2 3 import ( 4 "fmt" 5 "math" 6 "time" 7 8 "github.com/ethereum-optimism/optimism/op-node/rollup" 9 pubsub "github.com/libp2p/go-libp2p-pubsub" 10 "github.com/libp2p/go-libp2p/core/peer" 11 ) 12 13 // DecayToZero is the decay factor for a peer's score to zero. 14 const DecayToZero = 0.01 15 16 // MeshWeight is the weight of the mesh delivery topic. 17 const MeshWeight = -0.7 18 19 // MaxInMeshScore is the maximum score for being in the mesh. 20 const MaxInMeshScore = 10 21 22 // DecayEpoch is the number of epochs to decay the score over. 23 const DecayEpoch = time.Duration(5) 24 25 // ScoreDecay returns the decay factor for a given duration. 26 func ScoreDecay(duration time.Duration, slot time.Duration) float64 { 27 numOfTimes := duration / slot 28 return math.Pow(DecayToZero, 1/float64(numOfTimes)) 29 } 30 31 // LightPeerScoreParams is an instantiation of [pubsub.PeerScoreParams] with light penalties. 32 // See [PeerScoreParams] for detailed documentation. 33 // 34 // [PeerScoreParams]: https://pkg.go.dev/github.com/libp2p/go-libp2p-pubsub@v0.8.1#PeerScoreParams 35 func LightPeerScoreParams(cfg *rollup.Config) pubsub.PeerScoreParams { 36 slot := time.Duration(cfg.BlockTime) * time.Second 37 if slot == 0 { 38 slot = 2 * time.Second 39 } 40 // We initialize an "epoch" as 6 blocks suggesting 6 blocks, 41 // each taking ~ 2 seconds, is 12 seconds 42 epoch := 6 * slot 43 tenEpochs := 10 * epoch 44 oneHundredEpochs := 100 * epoch 45 invalidDecayPeriod := 50 * epoch 46 return pubsub.PeerScoreParams{ 47 Topics: map[string]*pubsub.TopicScoreParams{ 48 blocksTopicV1(cfg): { 49 TopicWeight: 0.8, 50 TimeInMeshWeight: MaxInMeshScore / inMeshCap(slot), 51 TimeInMeshQuantum: slot, 52 TimeInMeshCap: inMeshCap(slot), 53 FirstMessageDeliveriesWeight: 1, 54 FirstMessageDeliveriesDecay: ScoreDecay(20*epoch, slot), 55 FirstMessageDeliveriesCap: 23, 56 MeshMessageDeliveriesWeight: MeshWeight, 57 MeshMessageDeliveriesDecay: ScoreDecay(DecayEpoch*epoch, slot), 58 MeshMessageDeliveriesCap: float64(uint64(epoch/slot) * uint64(DecayEpoch)), 59 MeshMessageDeliveriesThreshold: float64(uint64(epoch/slot) * uint64(DecayEpoch) / 10), 60 MeshMessageDeliveriesWindow: 2 * time.Second, 61 MeshMessageDeliveriesActivation: 4 * epoch, 62 MeshFailurePenaltyWeight: MeshWeight, 63 MeshFailurePenaltyDecay: ScoreDecay(DecayEpoch*epoch, slot), 64 InvalidMessageDeliveriesWeight: -140.4475, 65 InvalidMessageDeliveriesDecay: ScoreDecay(invalidDecayPeriod, slot), 66 }, 67 }, 68 TopicScoreCap: 34, 69 AppSpecificScore: func(p peer.ID) float64 { 70 return 0 71 }, 72 AppSpecificWeight: 1, 73 IPColocationFactorWeight: -35, 74 IPColocationFactorThreshold: 10, 75 IPColocationFactorWhitelist: nil, 76 BehaviourPenaltyWeight: -16, 77 BehaviourPenaltyThreshold: 6, 78 BehaviourPenaltyDecay: ScoreDecay(tenEpochs, slot), 79 DecayInterval: slot, 80 DecayToZero: DecayToZero, 81 RetainScore: oneHundredEpochs, 82 } 83 } 84 85 // the cap for `inMesh` time scoring. 86 func inMeshCap(slot time.Duration) float64 { 87 return float64((3600 * time.Second) / slot) 88 } 89 90 func GetScoringParams(name string, cfg *rollup.Config) (*ScoringParams, error) { 91 switch name { 92 case "light": 93 return &ScoringParams{ 94 PeerScoring: LightPeerScoreParams(cfg), 95 ApplicationScoring: LightApplicationScoreParams(cfg), 96 }, nil 97 case "none": 98 return nil, nil 99 default: 100 return nil, fmt.Errorf("unknown p2p scoring level: %v", name) 101 } 102 } 103 104 // NewPeerScoreThresholds returns a default [pubsub.PeerScoreThresholds]. 105 // See [PeerScoreThresholds] for detailed documentation. 106 // 107 // [PeerScoreThresholds]: https://pkg.go.dev/github.com/libp2p/go-libp2p-pubsub@v0.8.1#PeerScoreThresholds 108 func NewPeerScoreThresholds() pubsub.PeerScoreThresholds { 109 return pubsub.PeerScoreThresholds{ 110 SkipAtomicValidation: false, 111 GossipThreshold: -10, 112 PublishThreshold: -40, 113 GraylistThreshold: -40, 114 AcceptPXThreshold: 20, 115 OpportunisticGraftThreshold: 0.05, 116 } 117 }