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  }