go-libp2p-pubsub/trace.go

467 lines
8.4 KiB
Go
Raw Normal View History

2019-11-04 17:22:14 +00:00
package pubsub
import (
2019-11-11 17:25:58 +00:00
"time"
2019-11-04 17:22:14 +00:00
"github.com/libp2p/go-libp2p-core/peer"
"github.com/libp2p/go-libp2p-core/protocol"
2019-11-11 17:25:58 +00:00
pb "github.com/libp2p/go-libp2p-pubsub/pb"
2019-11-04 17:22:14 +00:00
)
// Generic event tracer interface
type EventTracer interface {
Trace(evt *pb.TraceEvent)
2019-11-04 17:22:14 +00:00
}
2020-02-28 12:32:14 +00:00
// internal interface for score tracing
type internalTracer interface {
2020-02-28 12:32:14 +00:00
AddPeer(p peer.ID, proto protocol.ID)
RemovePeer(p peer.ID)
Join(topic string)
Leave(topic string)
Graft(p peer.ID, topic string)
Prune(p peer.ID, topic string)
ValidateMessage(msg *Message)
2020-02-28 12:32:14 +00:00
DeliverMessage(msg *Message)
RejectMessage(msg *Message, reason string)
DuplicateMessage(msg *Message)
}
2019-11-12 13:05:40 +00:00
// pubsub tracer details
2019-11-04 17:22:14 +00:00
type pubsubTracer struct {
tracer EventTracer
internal []internalTracer
pid peer.ID
msgID MsgIdFunction
2019-11-04 17:22:14 +00:00
}
2019-11-04 18:04:55 +00:00
func (t *pubsubTracer) PublishMessage(msg *Message) {
2019-11-11 17:25:58 +00:00
if t == nil {
return
2019-11-04 18:04:55 +00:00
}
2019-11-11 17:25:58 +00:00
2020-02-28 12:32:14 +00:00
if t.tracer == nil {
return
}
2019-11-11 17:25:58 +00:00
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_PUBLISH_MESSAGE.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
PublishMessage: &pb.TraceEvent_PublishMessage{
MessageID: []byte(t.msgID(msg.Message)),
2019-11-11 20:11:30 +00:00
Topics: msg.Message.TopicIDs,
2019-11-11 17:25:58 +00:00
},
}
t.tracer.Trace(evt)
2019-11-04 18:04:55 +00:00
}
func (t *pubsubTracer) ValidateMessage(msg *Message) {
if t == nil {
return
}
if msg.ReceivedFrom != t.pid {
for _, tr := range t.internal {
tr.ValidateMessage(msg)
}
}
}
2019-11-04 17:22:14 +00:00
func (t *pubsubTracer) RejectMessage(msg *Message, reason string) {
2019-11-11 17:25:58 +00:00
if t == nil {
return
2019-11-04 17:22:14 +00:00
}
2019-11-11 17:25:58 +00:00
if msg.ReceivedFrom != t.pid {
for _, tr := range t.internal {
tr.RejectMessage(msg, reason)
}
2020-02-28 12:32:14 +00:00
}
if t.tracer == nil {
return
}
2019-11-11 17:25:58 +00:00
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_REJECT_MESSAGE.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
RejectMessage: &pb.TraceEvent_RejectMessage{
MessageID: []byte(t.msgID(msg.Message)),
2019-11-11 17:25:58 +00:00
ReceivedFrom: []byte(msg.ReceivedFrom),
Reason: &reason,
Topics: msg.TopicIDs,
2019-11-11 17:25:58 +00:00
},
}
t.tracer.Trace(evt)
2019-11-04 17:22:14 +00:00
}
func (t *pubsubTracer) DuplicateMessage(msg *Message) {
2019-11-11 17:25:58 +00:00
if t == nil {
return
2019-11-04 17:22:14 +00:00
}
2019-11-11 17:25:58 +00:00
if msg.ReceivedFrom != t.pid {
for _, tr := range t.internal {
tr.DuplicateMessage(msg)
}
2020-02-28 12:32:14 +00:00
}
if t.tracer == nil {
return
}
2019-11-11 17:25:58 +00:00
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_DUPLICATE_MESSAGE.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
DuplicateMessage: &pb.TraceEvent_DuplicateMessage{
MessageID: []byte(t.msgID(msg.Message)),
2019-11-11 17:25:58 +00:00
ReceivedFrom: []byte(msg.ReceivedFrom),
Topics: msg.TopicIDs,
2019-11-11 17:25:58 +00:00
},
}
t.tracer.Trace(evt)
2019-11-04 17:22:14 +00:00
}
func (t *pubsubTracer) DeliverMessage(msg *Message) {
2019-11-11 17:25:58 +00:00
if t == nil {
return
}
if msg.ReceivedFrom != t.pid {
for _, tr := range t.internal {
tr.DeliverMessage(msg)
}
2020-02-28 12:32:14 +00:00
}
if t.tracer == nil {
return
}
2019-11-11 17:25:58 +00:00
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_DELIVER_MESSAGE.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
DeliverMessage: &pb.TraceEvent_DeliverMessage{
MessageID: []byte(t.msgID(msg.Message)),
Topics: msg.TopicIDs,
2019-11-11 17:25:58 +00:00
},
2019-11-04 17:22:14 +00:00
}
2019-11-11 17:25:58 +00:00
t.tracer.Trace(evt)
2019-11-04 17:22:14 +00:00
}
func (t *pubsubTracer) AddPeer(p peer.ID, proto protocol.ID) {
2019-11-11 17:25:58 +00:00
if t == nil {
return
}
for _, tr := range t.internal {
tr.AddPeer(p, proto)
2020-02-28 12:32:14 +00:00
}
if t.tracer == nil {
return
}
2019-11-11 17:25:58 +00:00
protoStr := string(proto)
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_ADD_PEER.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
AddPeer: &pb.TraceEvent_AddPeer{
PeerID: []byte(p),
Proto: &protoStr,
},
2019-11-04 17:22:14 +00:00
}
2019-11-11 17:25:58 +00:00
t.tracer.Trace(evt)
2019-11-04 17:22:14 +00:00
}
func (t *pubsubTracer) RemovePeer(p peer.ID) {
2019-11-11 17:25:58 +00:00
if t == nil {
return
}
for _, tr := range t.internal {
tr.RemovePeer(p)
2020-02-28 12:32:14 +00:00
}
if t.tracer == nil {
return
}
2019-11-11 17:25:58 +00:00
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_REMOVE_PEER.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
RemovePeer: &pb.TraceEvent_RemovePeer{
PeerID: []byte(p),
},
2019-11-04 17:22:14 +00:00
}
2019-11-11 17:25:58 +00:00
t.tracer.Trace(evt)
2019-11-04 17:22:14 +00:00
}
func (t *pubsubTracer) RecvRPC(rpc *RPC) {
2019-11-11 17:25:58 +00:00
if t == nil {
return
}
2020-02-28 12:32:14 +00:00
if t.tracer == nil {
return
}
2019-11-11 17:25:58 +00:00
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_RECV_RPC.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
RecvRPC: &pb.TraceEvent_RecvRPC{
ReceivedFrom: []byte(rpc.from),
Meta: t.traceRPCMeta(rpc),
2019-11-11 17:25:58 +00:00
},
2019-11-04 17:22:14 +00:00
}
2019-11-11 17:25:58 +00:00
t.tracer.Trace(evt)
2019-11-04 17:22:14 +00:00
}
func (t *pubsubTracer) SendRPC(rpc *RPC, p peer.ID) {
if t == nil {
return
2019-11-04 17:22:14 +00:00
}
2020-02-28 12:32:14 +00:00
if t.tracer == nil {
return
}
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_SEND_RPC.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
SendRPC: &pb.TraceEvent_SendRPC{
SendTo: []byte(p),
Meta: t.traceRPCMeta(rpc),
},
}
t.tracer.Trace(evt)
2019-11-04 17:22:14 +00:00
}
func (t *pubsubTracer) DropRPC(rpc *RPC, p peer.ID) {
if t == nil {
return
2019-11-04 17:22:14 +00:00
}
2020-02-28 12:32:14 +00:00
if t.tracer == nil {
return
}
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_DROP_RPC.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
DropRPC: &pb.TraceEvent_DropRPC{
SendTo: []byte(p),
Meta: t.traceRPCMeta(rpc),
},
}
t.tracer.Trace(evt)
2019-11-04 17:22:14 +00:00
}
func (t *pubsubTracer) traceRPCMeta(rpc *RPC) *pb.TraceEvent_RPCMeta {
2019-11-11 17:25:58 +00:00
rpcMeta := new(pb.TraceEvent_RPCMeta)
2019-11-11 20:11:30 +00:00
var msgs []*pb.TraceEvent_MessageMeta
2019-11-11 17:25:58 +00:00
for _, m := range rpc.Publish {
2019-11-11 20:11:30 +00:00
msgs = append(msgs, &pb.TraceEvent_MessageMeta{
MessageID: []byte(t.msgID(m)),
2019-11-11 20:11:30 +00:00
Topics: m.TopicIDs,
})
2019-11-11 17:25:58 +00:00
}
2019-11-11 20:11:30 +00:00
rpcMeta.Messages = msgs
2019-11-11 17:25:58 +00:00
var subs []*pb.TraceEvent_SubMeta
for _, sub := range rpc.Subscriptions {
subs = append(subs, &pb.TraceEvent_SubMeta{
Subscribe: sub.Subscribe,
Topic: sub.Topicid,
})
}
rpcMeta.Subscription = subs
if rpc.Control != nil {
var ihave []*pb.TraceEvent_ControlIHaveMeta
for _, ctl := range rpc.Control.Ihave {
var mids [][]byte
for _, mid := range ctl.MessageIDs {
mids = append(mids, []byte(mid))
}
ihave = append(ihave, &pb.TraceEvent_ControlIHaveMeta{
Topic: ctl.TopicID,
MessageIDs: mids,
})
}
var iwant []*pb.TraceEvent_ControlIWantMeta
for _, ctl := range rpc.Control.Iwant {
var mids [][]byte
for _, mid := range ctl.MessageIDs {
mids = append(mids, []byte(mid))
}
iwant = append(iwant, &pb.TraceEvent_ControlIWantMeta{
MessageIDs: mids,
})
}
var graft []*pb.TraceEvent_ControlGraftMeta
for _, ctl := range rpc.Control.Graft {
graft = append(graft, &pb.TraceEvent_ControlGraftMeta{
Topic: ctl.TopicID,
})
}
var prune []*pb.TraceEvent_ControlPruneMeta
for _, ctl := range rpc.Control.Prune {
2019-11-23 15:08:05 +00:00
peers := make([][]byte, 0, len(ctl.Peers))
for _, pi := range ctl.Peers {
peers = append(peers, pi.PeerID)
}
2019-11-11 17:25:58 +00:00
prune = append(prune, &pb.TraceEvent_ControlPruneMeta{
Topic: ctl.TopicID,
2019-11-23 15:08:05 +00:00
Peers: peers,
2019-11-11 17:25:58 +00:00
})
}
rpcMeta.Control = &pb.TraceEvent_ControlMeta{
Ihave: ihave,
Iwant: iwant,
Graft: graft,
Prune: prune,
}
}
return rpcMeta
}
2019-11-04 17:22:14 +00:00
func (t *pubsubTracer) Join(topic string) {
2019-11-11 17:25:58 +00:00
if t == nil {
return
2019-11-04 17:22:14 +00:00
}
2019-11-11 17:25:58 +00:00
for _, tr := range t.internal {
tr.Join(topic)
2020-02-28 12:32:14 +00:00
}
if t.tracer == nil {
return
}
2019-11-11 17:25:58 +00:00
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_JOIN.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
Join: &pb.TraceEvent_Join{
Topic: &topic,
},
}
t.tracer.Trace(evt)
2019-11-04 17:22:14 +00:00
}
func (t *pubsubTracer) Leave(topic string) {
2019-11-11 17:25:58 +00:00
if t == nil {
return
2019-11-04 17:22:14 +00:00
}
2019-11-11 17:25:58 +00:00
for _, tr := range t.internal {
tr.Leave(topic)
2020-02-28 12:32:14 +00:00
}
if t.tracer == nil {
return
}
2019-11-11 17:25:58 +00:00
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_LEAVE.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
Leave: &pb.TraceEvent_Leave{
Topic: &topic,
},
}
t.tracer.Trace(evt)
2019-11-04 17:22:14 +00:00
}
func (t *pubsubTracer) Graft(p peer.ID, topic string) {
2019-11-11 17:25:58 +00:00
if t == nil {
return
2019-11-04 17:22:14 +00:00
}
2019-11-11 17:25:58 +00:00
for _, tr := range t.internal {
tr.Graft(p, topic)
2020-02-28 12:32:14 +00:00
}
if t.tracer == nil {
return
}
2019-11-11 17:25:58 +00:00
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_GRAFT.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
Graft: &pb.TraceEvent_Graft{
PeerID: []byte(p),
Topic: &topic,
},
}
t.tracer.Trace(evt)
2019-11-04 17:22:14 +00:00
}
func (t *pubsubTracer) Prune(p peer.ID, topic string) {
2019-11-11 17:25:58 +00:00
if t == nil {
return
}
for _, tr := range t.internal {
tr.Prune(p, topic)
2020-02-28 12:32:14 +00:00
}
if t.tracer == nil {
return
}
2019-11-11 17:25:58 +00:00
now := time.Now().UnixNano()
evt := &pb.TraceEvent{
Type: pb.TraceEvent_PRUNE.Enum(),
PeerID: []byte(t.pid),
Timestamp: &now,
Prune: &pb.TraceEvent_Prune{
PeerID: []byte(p),
Topic: &topic,
},
2019-11-04 17:22:14 +00:00
}
2019-11-11 17:25:58 +00:00
t.tracer.Trace(evt)
2019-11-04 17:22:14 +00:00
}