github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/network/p2p/unicast/protocols/protocol.go (about)

     1  package protocols
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	libp2pnet "github.com/libp2p/go-libp2p/core/network"
     8  	"github.com/libp2p/go-libp2p/core/protocol"
     9  	"github.com/rs/zerolog"
    10  
    11  	"github.com/onflow/flow-go/model/flow"
    12  )
    13  
    14  // Flow Libp2p protocols
    15  const (
    16  	// FlowLibP2PProtocolCommonPrefix is the common prefix for all Libp2p protocol IDs used for Flow
    17  	// ALL Flow libp2p protocols must start with this prefix.
    18  	FlowLibP2PProtocolCommonPrefix = "/flow"
    19  
    20  	FlowDHTProtocolIDPrefix = FlowLibP2PProtocolCommonPrefix + "/dht/"
    21  
    22  	// FlowLibP2POneToOneProtocolIDPrefix is a unique Libp2p protocol ID prefix for Flow (https://docs.libp2p.io/concepts/protocols/)
    23  	// All nodes communicate with each other using this protocol id suffixed with the id of the root block
    24  	FlowLibP2POneToOneProtocolIDPrefix = FlowLibP2PProtocolCommonPrefix + "/push/"
    25  
    26  	// FlowLibP2PPingProtocolPrefix is the Flow Ping protocol prefix
    27  	FlowLibP2PPingProtocolPrefix = FlowLibP2PProtocolCommonPrefix + "/ping/"
    28  
    29  	// FlowLibP2PProtocolGzipCompressedOneToOne represents the protocol id for compressed streams under gzip compressor.
    30  	FlowLibP2PProtocolGzipCompressedOneToOne = FlowLibP2POneToOneProtocolIDPrefix + "/gzip/"
    31  )
    32  
    33  // IsFlowProtocolStream returns true if the libp2p stream is for a Flow protocol
    34  func IsFlowProtocolStream(s libp2pnet.Stream) bool {
    35  	p := string(s.Protocol())
    36  	return strings.HasPrefix(p, FlowLibP2PProtocolCommonPrefix)
    37  }
    38  
    39  func FlowDHTProtocolID(sporkId flow.Identifier) protocol.ID {
    40  	return protocol.ID(FlowDHTProtocolIDPrefix + sporkId.String())
    41  }
    42  
    43  func FlowPublicDHTProtocolID(sporkId flow.Identifier) protocol.ID {
    44  	return protocol.ID(FlowDHTProtocolIDPrefix + "public/" + sporkId.String())
    45  }
    46  
    47  func FlowProtocolID(sporkId flow.Identifier) protocol.ID {
    48  	return protocol.ID(FlowLibP2POneToOneProtocolIDPrefix + sporkId.String())
    49  }
    50  
    51  func PingProtocolId(sporkId flow.Identifier) protocol.ID {
    52  	return protocol.ID(FlowLibP2PPingProtocolPrefix + sporkId.String())
    53  }
    54  
    55  type ProtocolName string
    56  type ProtocolFactory func(zerolog.Logger, flow.Identifier, libp2pnet.StreamHandler) Protocol
    57  
    58  func ToProtocolNames(names []string) []ProtocolName {
    59  	p := make([]ProtocolName, 0)
    60  	for _, name := range names {
    61  		p = append(p, ProtocolName(strings.Trim(name, " ")))
    62  	}
    63  	return p
    64  }
    65  
    66  func ToProtocolFactory(name ProtocolName) (ProtocolFactory, error) {
    67  	switch name {
    68  	case GzipCompressionUnicast:
    69  		return func(logger zerolog.Logger, sporkId flow.Identifier, handler libp2pnet.StreamHandler) Protocol {
    70  			return NewGzipCompressedUnicast(logger, sporkId, handler)
    71  		}, nil
    72  	default:
    73  		return nil, fmt.Errorf("unknown unicast protocol name: %s", name)
    74  	}
    75  }
    76  
    77  // Protocol represents a unicast protocol.
    78  type Protocol interface {
    79  	// UpgradeRawStream wraps a specific unicast protocol implementation around
    80  	// the plain libp2p stream.
    81  	UpgradeRawStream(s libp2pnet.Stream) (libp2pnet.Stream, error)
    82  	// Handler is a libp2p stream handler that implements the logic of handling
    83  	// an established incoming stream to this node.
    84  	Handler(stream libp2pnet.Stream)
    85  	// ProtocolId returns the libp2p protocol id associated to this protocol. In libp2p
    86  	// streams running with the same protocol are identified with the same  protocol id.
    87  	ProtocolId() protocol.ID
    88  }