github.com/koko1123/flow-go-1@v0.29.6/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/koko1123/flow-go-1/model/flow"
    11  	"github.com/koko1123/flow-go-1/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/koko1123/flow-go-1/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/koko1123/flow-go-1/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", peerID)
    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  }