github.com/amazechain/amc@v0.1.3/internal/p2p/broadcaster.go (about) 1 package p2p 2 3 import ( 4 "bytes" 5 "context" 6 "fmt" 7 "reflect" 8 "time" 9 10 "github.com/pkg/errors" 11 ssz "github.com/prysmaticlabs/fastssz" 12 "go.opencensus.io/trace" 13 "google.golang.org/protobuf/proto" 14 ) 15 16 const ( 17 //todo 18 maxBroadcastTime = 8 * time.Second 19 ) 20 21 // ErrMessageNotMapped occurs on a Broadcast attempt when a message has not been defined in the 22 // GossipTypeMapping. 23 var ErrMessageNotMapped = errors.New("message type is not mapped to a PubSub topic") 24 25 // Broadcast a message to the p2p network, the message is assumed to be 26 // broadcasted to the current fork. 27 func (s *Service) Broadcast(ctx context.Context, msg proto.Message) error { 28 ctx, span := trace.StartSpan(ctx, "p2p.Broadcast") 29 defer span.End() 30 31 ctx, cancel := context.WithTimeout(ctx, maxBroadcastTime) 32 defer cancel() 33 34 forkDigest, err := s.currentForkDigest() 35 if err != nil { 36 err := errors.Wrap(err, "could not retrieve fork digest") 37 //tracing.AnnotateError(span, err) 38 return err 39 } 40 41 topic, ok := GossipTypeMapping[reflect.TypeOf(msg)] 42 if !ok { 43 //tracing.AnnotateError(span, ErrMessageNotMapped) 44 return ErrMessageNotMapped 45 } 46 castMsg, ok := msg.(ssz.Marshaler) 47 if !ok { 48 return errors.Errorf("message of %T does not support marshaller interface", msg) 49 } 50 return s.broadcastObject(ctx, castMsg, fmt.Sprintf(topic, forkDigest)) 51 } 52 53 // method to broadcast messages to other peers in our gossip mesh. 54 func (s *Service) broadcastObject(ctx context.Context, obj ssz.Marshaler, topic string) error { 55 ctx, span := trace.StartSpan(ctx, "p2p.broadcastObject") 56 defer span.End() 57 58 span.AddAttributes(trace.StringAttribute("topic", topic)) 59 60 buf := new(bytes.Buffer) 61 if _, err := s.Encoding().EncodeGossip(buf, obj); err != nil { 62 err := errors.Wrap(err, "could not encode message") 63 //tracing.AnnotateError(span, err) 64 return err 65 } 66 67 if span.IsRecordingEvents() { 68 //todo 69 //id := utils.Hash(buf.Bytes()) 70 //messageLen := int64(buf.Len()) 71 //// lint:ignore uintcast -- It's safe to do this for tracing. 72 //iid := int64(id) 73 //span.AddMessageSendEvent(iid, messageLen /*uncompressed*/, messageLen /*compressed*/) 74 } 75 if err := s.PublishToTopic(ctx, topic+s.Encoding().ProtocolSuffix(), buf.Bytes()); err != nil { 76 err := errors.Wrap(err, "could not publish message") 77 //tracing.AnnotateError(span, err) 78 return err 79 } 80 return nil 81 }