github.com/amazechain/amc@v0.1.3/internal/p2p/sender.go (about)

     1  package p2p
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/kr/pretty"
     8  	"github.com/libp2p/go-libp2p/core/network"
     9  	"github.com/libp2p/go-libp2p/core/peer"
    10  	"github.com/libp2p/go-libp2p/core/protocol"
    11  	"github.com/pkg/errors"
    12  	ssz "github.com/prysmaticlabs/fastssz"
    13  	"go.opencensus.io/trace"
    14  )
    15  
    16  // Send a message to a specific peer. The returned stream may be used for reading, but has been
    17  // closed for writing.
    18  //
    19  // When done, the caller must Close or Reset on the stream.
    20  func (s *Service) Send(ctx context.Context, message interface{}, baseTopic string, pid peer.ID) (network.Stream, error) {
    21  	ctx, span := trace.StartSpan(ctx, "p2p.Send")
    22  	defer span.End()
    23  	if err := VerifyTopicMapping(baseTopic, message); err != nil {
    24  		return nil, err
    25  	}
    26  	topic := baseTopic + s.Encoding().ProtocolSuffix()
    27  	span.AddAttributes(trace.StringAttribute("topic", topic))
    28  
    29  	log.Trace(fmt.Sprintf("Sending RPC request to peer %s", pid.String()), "topic", topic, "request", pretty.Sprint(message))
    30  
    31  	// Apply max dial timeout when opening a new stream.
    32  	ctx, cancel := context.WithTimeout(ctx, maxDialTimeout)
    33  	defer cancel()
    34  
    35  	stream, err := s.host.NewStream(ctx, pid, protocol.ID(topic))
    36  	if err != nil {
    37  		//tracing.AnnotateError(span, err)
    38  		return nil, err
    39  	}
    40  	castedMsg, ok := message.(ssz.Marshaler)
    41  	if !ok {
    42  		return nil, errors.Errorf("%T does not support the ssz marshaller interface", message)
    43  	}
    44  	if _, err := s.Encoding().EncodeWithMaxLength(stream, castedMsg); err != nil {
    45  		//tracing.AnnotateError(span, err)
    46  		_err := stream.Reset()
    47  		_ = _err
    48  		return nil, err
    49  	}
    50  
    51  	// Close stream for writing.
    52  	if err := stream.CloseWrite(); err != nil {
    53  		//tracing.AnnotateError(span, err)
    54  		_err := stream.Reset()
    55  		_ = _err
    56  		return nil, err
    57  	}
    58  
    59  	return stream, nil
    60  }