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  }