mirror of
https://github.com/libp2p/go-libp2p-core.git
synced 2025-01-29 04:40:10 +08:00
feat: support encoding/decoding peer IDs as CIDs _in text_
This commit is contained in:
parent
2f75277a8d
commit
dc718fa4da
73
peer/peer.go
73
peer/peer.go
@ -5,7 +5,9 @@ import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
cid "github.com/ipfs/go-cid"
|
||||
ic "github.com/libp2p/go-libp2p-core/crypto"
|
||||
b58 "github.com/mr-tron/base58/base58"
|
||||
mh "github.com/multiformats/go-multihash"
|
||||
@ -129,23 +131,24 @@ func IDFromBytes(b []byte) (ID, error) {
|
||||
return ID(b), nil
|
||||
}
|
||||
|
||||
// IDB58Decode accepts a base58-encoded multihash representing a peer ID
|
||||
// and returns the decoded ID if the input is valid.
|
||||
// IDB58Decode decodes a peer ID.
|
||||
//
|
||||
// Deprecated: Use Decode.
|
||||
func IDB58Decode(s string) (ID, error) {
|
||||
m, err := mh.FromB58String(s)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ID(m), err
|
||||
return Decode(s)
|
||||
}
|
||||
|
||||
// IDB58Encode returns the base58-encoded multihash representation of the ID.
|
||||
//
|
||||
// Deprecated: Use Encode.
|
||||
func IDB58Encode(id ID) string {
|
||||
return b58.Encode([]byte(id))
|
||||
}
|
||||
|
||||
// IDHexDecode accepts a hex-encoded multihash representing a peer ID
|
||||
// and returns the decoded ID if the input is valid.
|
||||
//
|
||||
// Deprecated: Don't raw-hex encode peer IDs, use base16 CIDs.
|
||||
func IDHexDecode(s string) (ID, error) {
|
||||
m, err := mh.FromHexString(s)
|
||||
if err != nil {
|
||||
@ -155,10 +158,66 @@ func IDHexDecode(s string) (ID, error) {
|
||||
}
|
||||
|
||||
// IDHexEncode returns the hex-encoded multihash representation of the ID.
|
||||
//
|
||||
// Deprecated: Don't raw-hex encode peer IDs, use base16 CIDs.
|
||||
func IDHexEncode(id ID) string {
|
||||
return hex.EncodeToString([]byte(id))
|
||||
}
|
||||
|
||||
// Decode accepts an encoded peer ID and returns the decoded ID if the input is
|
||||
// valid.
|
||||
//
|
||||
// The encoded peer ID can either be a CID of a key or a raw multihash (identity
|
||||
// or sha256-256).
|
||||
func Decode(s string) (ID, error) {
|
||||
if strings.HasPrefix(s, "Qm") || strings.HasPrefix(s, "1") {
|
||||
// base58 encoded sha256 or identity multihash
|
||||
m, err := mh.FromB58String(s)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to parse peer ID: %s", err)
|
||||
}
|
||||
return ID(m), nil
|
||||
}
|
||||
|
||||
c, err := cid.Decode(s)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to parse peer ID: %s", err)
|
||||
}
|
||||
return FromCid(c)
|
||||
}
|
||||
|
||||
// Encode encodes a peer ID as a string.
|
||||
//
|
||||
// At the moment, it base58 encodes the peer ID but, in the future, it will
|
||||
// switch to encoding it as a CID by default.
|
||||
func Encode(id ID) string {
|
||||
return IDB58Encode(id)
|
||||
}
|
||||
|
||||
// FromCid converts a CID to a peer ID, if possible.
|
||||
func FromCid(c cid.Cid) (ID, error) {
|
||||
ty := c.Type()
|
||||
if ty != cid.Libp2pKey {
|
||||
s := cid.CodecToStr[ty]
|
||||
if s == "" {
|
||||
s = fmt.Sprintf("[unknown multicodec %d]", ty)
|
||||
}
|
||||
return "", fmt.Errorf("can't convert CID of type %s to a peer ID", s)
|
||||
}
|
||||
return ID(c.Hash()), nil
|
||||
}
|
||||
|
||||
// ToCid encodes a peer ID as a CID of the public key.
|
||||
//
|
||||
// If the peer ID is invalid (e.g., empty), this will return the empty CID.
|
||||
func ToCid(id ID) cid.Cid {
|
||||
m, err := mh.Cast([]byte(id))
|
||||
if err != nil {
|
||||
return cid.Cid{}
|
||||
}
|
||||
return cid.NewCidV1(cid.Libp2pKey, m)
|
||||
}
|
||||
|
||||
// IDFromPublicKey returns the Peer ID corresponding to the public key pk.
|
||||
func IDFromPublicKey(pk ic.PubKey) (ID, error) {
|
||||
b, err := pk.Bytes()
|
||||
|
@ -153,6 +153,51 @@ func TestIDMatchesPrivateKey(t *testing.T) {
|
||||
test(man)
|
||||
}
|
||||
|
||||
func TestIDEncoding(t *testing.T) {
|
||||
test := func(ks keyset) {
|
||||
p1, err := IDB58Decode(ks.hpkp)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if ks.hpk != string(p1) {
|
||||
t.Error("p1 and hpk differ")
|
||||
}
|
||||
|
||||
c := ToCid(p1)
|
||||
p2, err := FromCid(c)
|
||||
if err != nil || p1 != p2 {
|
||||
t.Fatal("failed to round-trip through CID:", err)
|
||||
}
|
||||
p3, err := Decode(c.String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if p3 != p1 {
|
||||
t.Fatal("failed to round trip through CID string")
|
||||
}
|
||||
|
||||
if ks.hpkp != Encode(p1) {
|
||||
t.Fatal("should always encode peer IDs as base58 by default")
|
||||
}
|
||||
}
|
||||
|
||||
test(gen1)
|
||||
test(gen2)
|
||||
test(man)
|
||||
|
||||
exampleCid := "bafkreifoybygix7fh3r3g5rqle3wcnhqldgdg4shzf4k3ulyw3gn7mabt4"
|
||||
_, err := Decode(exampleCid)
|
||||
if err == nil {
|
||||
t.Fatal("should refuse to decode a non-peer ID CID")
|
||||
}
|
||||
|
||||
c := ToCid("")
|
||||
if c.Defined() {
|
||||
t.Fatal("cid of empty peer ID should have been undefined")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPublicKeyExtraction(t *testing.T) {
|
||||
t.Skip("disabled until libp2p/go-libp2p-crypto#51 is fixed")
|
||||
// Happy path
|
||||
|
Loading…
Reference in New Issue
Block a user