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 }