mirror of
https://github.com/logos-messaging/go-libp2p-pubsub.git
synced 2026-05-05 16:19:32 +00:00
extended peer score inspection
This commit is contained in:
parent
ae55bf9603
commit
cce1f8a107
89
score.go
89
score.go
@ -78,6 +78,7 @@ type peerScore struct {
|
|||||||
|
|
||||||
// debugging inspection
|
// debugging inspection
|
||||||
inspect PeerScoreInspectFn
|
inspect PeerScoreInspectFn
|
||||||
|
inspectEx ExtendedPeerScoreInspectFn
|
||||||
inspectPeriod time.Duration
|
inspectPeriod time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,12 +115,33 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type PeerScoreInspectFn func(map[peer.ID]float64)
|
type PeerScoreInspectFn func(map[peer.ID]float64)
|
||||||
|
type ExtendedPeerScoreInspectFn func(map[peer.ID]*PeerScoreSnapshot)
|
||||||
|
|
||||||
|
type PeerScoreSnapshot struct {
|
||||||
|
Score float64
|
||||||
|
Topics map[string]*TopicScoreSnapshot
|
||||||
|
AppSpecificScore float64
|
||||||
|
IPColocationFactor int
|
||||||
|
BehaviourPenalty float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type TopicScoreSnapshot struct {
|
||||||
|
TimeInMesh time.Duration
|
||||||
|
FirstMessageDeliveries float64
|
||||||
|
MeshMessageDeliveries float64
|
||||||
|
InvalidMessageDeliveries float64
|
||||||
|
}
|
||||||
|
|
||||||
// WithPeerScoreInspect is a gossipsub router option that enables peer score debugging.
|
// WithPeerScoreInspect is a gossipsub router option that enables peer score debugging.
|
||||||
// When this option is enabled, the supplied function will be invoked periodically to allow
|
// When this option is enabled, the supplied function will be invoked periodically to allow
|
||||||
// the application to inspec or dump the scores for connected peers.
|
// the application to inspect or dump the scores for connected peers.
|
||||||
|
// The supplied function can have one of two signatures:
|
||||||
|
// - PeerScoreInspectFn, which takes a map of peer IDs to score.
|
||||||
|
// - ExtendedPeerScoreInspectFn, which takes a map of peer IDs to
|
||||||
|
// PeerScoreSnapshots and allows inspection of individual score
|
||||||
|
// components for debugging peer scoring.
|
||||||
// This option must be passed _after_ the WithPeerScore option.
|
// This option must be passed _after_ the WithPeerScore option.
|
||||||
func WithPeerScoreInspect(inspect PeerScoreInspectFn, period time.Duration) Option {
|
func WithPeerScoreInspect(inspect interface{}, period time.Duration) Option {
|
||||||
return func(ps *PubSub) error {
|
return func(ps *PubSub) error {
|
||||||
gs, ok := ps.rt.(*GossipSubRouter)
|
gs, ok := ps.rt.(*GossipSubRouter)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -130,7 +152,19 @@ func WithPeerScoreInspect(inspect PeerScoreInspectFn, period time.Duration) Opti
|
|||||||
return fmt.Errorf("peer scoring is not enabled")
|
return fmt.Errorf("peer scoring is not enabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
gs.score.inspect = inspect
|
switch i := inspect.(type) {
|
||||||
|
case PeerScoreInspectFn:
|
||||||
|
gs.score.inspect = i
|
||||||
|
case func(map[peer.ID]float64):
|
||||||
|
gs.score.inspect = PeerScoreInspectFn(i)
|
||||||
|
case ExtendedPeerScoreInspectFn:
|
||||||
|
gs.score.inspectEx = i
|
||||||
|
case func(map[peer.ID]*PeerScoreSnapshot):
|
||||||
|
gs.score.inspectEx = ExtendedPeerScoreInspectFn(i)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown peer score insector type: %v", inspect)
|
||||||
|
}
|
||||||
|
|
||||||
gs.score.inspectPeriod = period
|
gs.score.inspectPeriod = period
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -290,7 +324,7 @@ func (ps *peerScore) background(ctx context.Context) {
|
|||||||
defer gcDeliveryRecords.Stop()
|
defer gcDeliveryRecords.Stop()
|
||||||
|
|
||||||
var inspectScores <-chan time.Time
|
var inspectScores <-chan time.Time
|
||||||
if ps.inspect != nil {
|
if ps.inspect != nil || ps.inspectEx != nil {
|
||||||
ticker := time.NewTicker(ps.inspectPeriod)
|
ticker := time.NewTicker(ps.inspectPeriod)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
// also dump at exit for one final sample
|
// also dump at exit for one final sample
|
||||||
@ -320,6 +354,14 @@ func (ps *peerScore) background(ctx context.Context) {
|
|||||||
|
|
||||||
// inspectScores dumps all tracked scores into the inspect function.
|
// inspectScores dumps all tracked scores into the inspect function.
|
||||||
func (ps *peerScore) inspectScores() {
|
func (ps *peerScore) inspectScores() {
|
||||||
|
if ps.inspect != nil {
|
||||||
|
ps.inspectScoresSimple()
|
||||||
|
} else if ps.inspectEx != nil {
|
||||||
|
ps.inspectScoresExtended()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps *peerScore) inspectScoresSimple() {
|
||||||
ps.Lock()
|
ps.Lock()
|
||||||
scores := make(map[peer.ID]float64, len(ps.peerStats))
|
scores := make(map[peer.ID]float64, len(ps.peerStats))
|
||||||
for p := range ps.peerStats {
|
for p := range ps.peerStats {
|
||||||
@ -334,6 +376,45 @@ func (ps *peerScore) inspectScores() {
|
|||||||
go ps.inspect(scores)
|
go ps.inspect(scores)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ps *peerScore) inspectScoresExtended() {
|
||||||
|
ps.Lock()
|
||||||
|
scores := make(map[peer.ID]*PeerScoreSnapshot, len(ps.peerStats))
|
||||||
|
for p, pstats := range ps.peerStats {
|
||||||
|
pss := new(PeerScoreSnapshot)
|
||||||
|
pss.Score = ps.score(p)
|
||||||
|
if len(pstats.topics) > 0 {
|
||||||
|
pss.Topics = make(map[string]*TopicScoreSnapshot, len(pstats.topics))
|
||||||
|
for t, ts := range pstats.topics {
|
||||||
|
pss.Topics[t] = &TopicScoreSnapshot{
|
||||||
|
FirstMessageDeliveries: ts.firstMessageDeliveries,
|
||||||
|
MeshMessageDeliveries: ts.meshMessageDeliveries,
|
||||||
|
InvalidMessageDeliveries: ts.invalidMessageDeliveries,
|
||||||
|
}
|
||||||
|
if ts.inMesh {
|
||||||
|
pss.Topics[t].TimeInMesh = ts.meshTime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pss.AppSpecificScore = ps.params.AppSpecificScore(p)
|
||||||
|
for _, ip := range pstats.ips {
|
||||||
|
_, whitelisted := ps.params.IPColocationFactorWhitelist[ip]
|
||||||
|
if whitelisted {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
peersInIP := len(ps.peerIPs[ip])
|
||||||
|
if peersInIP > ps.params.IPColocationFactorThreshold {
|
||||||
|
surpluss := peersInIP - ps.params.IPColocationFactorThreshold
|
||||||
|
pss.IPColocationFactor += surpluss
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pss.BehaviourPenalty = pstats.behaviourPenalty
|
||||||
|
scores[p] = pss
|
||||||
|
}
|
||||||
|
ps.Unlock()
|
||||||
|
|
||||||
|
go ps.inspectEx(scores)
|
||||||
|
}
|
||||||
|
|
||||||
// refreshScores decays scores, and purges score records for disconnected peers,
|
// refreshScores decays scores, and purges score records for disconnected peers,
|
||||||
// once their expiry has elapsed.
|
// once their expiry has elapsed.
|
||||||
func (ps *peerScore) refreshScores() {
|
func (ps *peerScore) refreshScores() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user