github.com/koko1123/flow-go-1@v0.29.6/network/p2p/utils/p2putils.go (about) 1 package utils 2 3 import ( 4 "fmt" 5 "net" 6 7 "github.com/libp2p/go-libp2p/core/peer" 8 "github.com/multiformats/go-multiaddr" 9 10 "github.com/koko1123/flow-go-1/model/flow" 11 "github.com/koko1123/flow-go-1/network/channels" 12 "github.com/koko1123/flow-go-1/network/internal/p2putils" 13 "github.com/onflow/flow-go/crypto/hash" 14 ) 15 16 // PeerAddressInfo generates the libp2p peer.AddrInfo for the given Flow.Identity. 17 // A node in flow is defined by a flow.Identity while it is defined by a peer.AddrInfo in libp2p. 18 // 19 // flow.Identity ---> peer.AddrInfo 20 // |-- Address ---> |-- []multiaddr.Multiaddr 21 // |-- NetworkPublicKey ---> |-- ID 22 func PeerAddressInfo(identity flow.Identity) (peer.AddrInfo, error) { 23 ip, port, key, err := p2putils.NetworkingInfo(identity) 24 if err != nil { 25 return peer.AddrInfo{}, fmt.Errorf("could not translate identity to networking info %s: %w", identity.NodeID.String(), err) 26 } 27 28 addr := MultiAddressStr(ip, port) 29 maddr, err := multiaddr.NewMultiaddr(addr) 30 if err != nil { 31 return peer.AddrInfo{}, err 32 } 33 34 id, err := peer.IDFromPublicKey(key) 35 if err != nil { 36 return peer.AddrInfo{}, fmt.Errorf("could not extract libp2p id from key:%w", err) 37 } 38 pInfo := peer.AddrInfo{ID: id, Addrs: []multiaddr.Multiaddr{maddr}} 39 return pInfo, err 40 } 41 42 // PeerInfosFromIDs converts the given flow.Identities to peer.AddrInfo. 43 // For each identity, if the conversion succeeds, the peer.AddrInfo is included in the result else it is 44 // included in the error map with the corresponding error 45 func PeerInfosFromIDs(ids flow.IdentityList) ([]peer.AddrInfo, map[flow.Identifier]error) { 46 validIDs := make([]peer.AddrInfo, 0, len(ids)) 47 invalidIDs := make(map[flow.Identifier]error) 48 for _, id := range ids { 49 peerInfo, err := PeerAddressInfo(*id) 50 if err != nil { 51 invalidIDs[id.NodeID] = err 52 continue 53 } 54 validIDs = append(validIDs, peerInfo) 55 } 56 return validIDs, invalidIDs 57 } 58 59 // MultiAddressStr receives a node ip and port and returns 60 // its corresponding Libp2p MultiAddressStr in string format 61 // in current implementation IP part of the node address is 62 // either an IP or a dns4. 63 // https://docs.libp2p.io/concepts/addressing/ 64 func MultiAddressStr(ip, port string) string { 65 parsedIP := net.ParseIP(ip) 66 if parsedIP != nil { 67 // returns parsed ip version of the multi-address 68 return fmt.Sprintf("/ip4/%s/tcp/%s", ip, port) 69 } 70 // could not parse it as an IP address and returns the dns version of the 71 // multi-address 72 return fmt.Sprintf("/dns4/%s/tcp/%s", ip, port) 73 } 74 75 // AllowedSubscription returns true if the given role is allowed to subscribe to the topic. 76 func AllowedSubscription(role flow.Role, topic string) bool { 77 channel, ok := channels.ChannelFromTopic(channels.Topic(topic)) 78 if !ok { 79 return false 80 } 81 82 if !role.Valid() { 83 // TODO: eventually we should have block proposals relayed on a separate 84 // channel on the public network. For now, we need to make sure that 85 // full observer nodes can subscribe to the block proposal channel. 86 return append(channels.PublicChannels(), channels.ReceiveBlocks).Contains(channel) 87 } else { 88 if roles, ok := channels.RolesByChannel(channel); ok { 89 return roles.Contains(role) 90 } 91 92 return false 93 } 94 } 95 96 // MessageID returns the hash of the given data (used to generate the message ID for pubsub messages). 97 func MessageID(data []byte) string { 98 h := hash.NewSHA3_384() 99 _, _ = h.Write(data) 100 return h.SumHash().Hex() 101 }