github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/network/p2p/translator/unstaked_translator.go (about) 1 package translator 2 3 import ( 4 "fmt" 5 6 "github.com/libp2p/go-libp2p/core/crypto" 7 crypto_pb "github.com/libp2p/go-libp2p/core/crypto/pb" 8 "github.com/libp2p/go-libp2p/core/peer" 9 10 "github.com/onflow/flow-go/model/flow" 11 "github.com/onflow/flow-go/network/p2p" 12 ) 13 14 // PublicNetworkIDTranslator implements an `p2p.IDTranslator` which translates IDs for peers 15 // on the unstaked network. 16 // On the unstaked network, a Flow ID is derived from a peer ID by extracting the public 17 // key from the peer ID, dropping the first byte (parity byte), and using the remaining 18 // 32 bytes as the Flow ID. 19 // Network keys for unstaked nodes must be generated using the Secp256k1 curve, and must 20 // be positive. It is assumed that these requirements are enforced during key generation, 21 // and any peer ID's which don't follow these conventions are considered invalid. 22 type PublicNetworkIDTranslator struct{} 23 24 // TODO Rename this one to NewPublicNetworkIDTranslator once observer changes are merged 25 func NewPublicNetworkIDTranslator() *PublicNetworkIDTranslator { 26 return &PublicNetworkIDTranslator{} 27 } 28 29 var _ p2p.IDTranslator = (*PublicNetworkIDTranslator)(nil) 30 31 // GetPeerID returns the peer ID for the given Flow ID. 32 // TODO: implement BFT-compliant error handling -> https://github.com/onflow/flow-go/blob/master/CodingConventions.md 33 func (t *PublicNetworkIDTranslator) GetPeerID(flowID flow.Identifier) (peer.ID, error) { 34 data := append([]byte{0x02}, flowID[:]...) 35 36 um := crypto.PubKeyUnmarshallers[crypto_pb.KeyType_Secp256k1] 37 key, err := um(data) 38 if err != nil { 39 return "", fmt.Errorf("failed to convert flow ID to libp2p public key: %w", err) 40 } 41 42 pid, err := peer.IDFromPublicKey(key) 43 if err != nil { 44 return "", fmt.Errorf("failed to get peer ID from libp2p public key: %w", err) 45 } 46 47 return pid, nil 48 } 49 50 // GetFlowID returns the Flow ID for the given peer ID. 51 // TODO: implement BFT-compliant error handling -> https://github.com/onflow/flow-go/blob/master/CodingConventions.md 52 func (t *PublicNetworkIDTranslator) GetFlowID(peerID peer.ID) (flow.Identifier, error) { 53 pk, err := peerID.ExtractPublicKey() 54 if err != nil { 55 return flow.ZeroID, fmt.Errorf("cannot generate an unstaked FlowID for peerID %v: corresponding libp2p key is not extractible from PeerID: %w", peerID, err) 56 } 57 58 if pk.Type() != crypto_pb.KeyType_Secp256k1 { 59 return flow.ZeroID, fmt.Errorf("cannot generate an unstaked FlowID for peerID %v: corresponding libp2p key is not a %v key", peerID, crypto_pb.KeyType_name[(int32)(crypto_pb.KeyType_Secp256k1)]) 60 } 61 62 data, err := pk.Raw() 63 if err != nil || data[0] != 0x02 { 64 return flow.ZeroID, fmt.Errorf("cannot generate an unstaked FlowID for peerID %v: corresponding libp2p key is invalid or negative", peerID) 65 } 66 67 return flow.HashToID(data[1:]), nil 68 }