Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a new type for peer id #2159

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions core/metrics/bandwidth.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,21 @@ func (bwc *BandwidthCounter) LogRecvMessage(size int64) {
// Bandwidth is associated with the given protocol.ID and peer.ID.
func (bwc *BandwidthCounter) LogSentMessageStream(size int64, proto protocol.ID, p peer.ID) {
bwc.protocolOut.Get(string(proto)).Mark(uint64(size))
bwc.peerOut.Get(string(p)).Mark(uint64(size))
bwc.peerOut.Get(string(p.MustMarshalBinary())).Mark(uint64(size))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not p.String()?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The old code used the bytes. This PR should not change anything semantically. If we used p.String() we would be changing semantics.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Let’s keep this change minimal. We can do a follow up PR if we want to change this interface.

}

// LogRecvMessageStream records the size of an incoming message over a single logical stream.
// Bandwidth is associated with the given protocol.ID and peer.ID.
func (bwc *BandwidthCounter) LogRecvMessageStream(size int64, proto protocol.ID, p peer.ID) {
bwc.protocolIn.Get(string(proto)).Mark(uint64(size))
bwc.peerIn.Get(string(p)).Mark(uint64(size))
bwc.peerIn.Get(string(p.MustMarshalBinary())).Mark(uint64(size))
}

// GetBandwidthForPeer returns a Stats struct with bandwidth metrics associated with the given peer.ID.
// The metrics returned include all traffic sent / received for the peer, regardless of protocol.
func (bwc *BandwidthCounter) GetBandwidthForPeer(p peer.ID) (out Stats) {
inSnap := bwc.peerIn.Get(string(p)).Snapshot()
outSnap := bwc.peerOut.Get(string(p)).Snapshot()
inSnap := bwc.peerIn.Get(string(p.MustMarshalBinary())).Snapshot()
outSnap := bwc.peerOut.Get(string(p.MustMarshalBinary())).Snapshot()

return Stats{
TotalIn: int64(inSnap.Total),
Expand Down Expand Up @@ -104,7 +104,10 @@ func (bwc *BandwidthCounter) GetBandwidthByPeer() map[peer.ID]Stats {
peers := make(map[peer.ID]Stats)

bwc.peerIn.ForEach(func(p string, meter *flow.Meter) {
id := peer.ID(p)
id, err := peer.IDFromBytes([]byte(p))
if err != nil {
return
}
snap := meter.Snapshot()

stat := peers[id]
Expand All @@ -114,7 +117,10 @@ func (bwc *BandwidthCounter) GetBandwidthByPeer() map[peer.ID]Stats {
})

bwc.peerOut.ForEach(func(p string, meter *flow.Meter) {
id := peer.ID(p)
id, err := peer.IDFromBytes([]byte(p))
if err != nil {
return
}
snap := meter.Snapshot()

stat := peers[id]
Expand Down
10 changes: 5 additions & 5 deletions core/metrics/bandwidth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import (
"testing"
"time"

"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/protocol"
"github.com/libp2p/go-libp2p/core/test"

"github.com/libp2p/go-flow-metrics"

Expand Down Expand Up @@ -36,7 +36,7 @@ func round(bwc *BandwidthCounter, b *testing.B) {
var wg sync.WaitGroup
wg.Add(10000)
for i := 0; i < 1000; i++ {
p := peer.ID(fmt.Sprintf("peer-%d", i))
p := test.MustPeerIDFromSeed(fmt.Sprintf("peer-%d", i))
for j := 0; j < 10; j++ {
proto := protocol.ID(fmt.Sprintf("bitswap-%d", j))
go func() {
Expand All @@ -62,7 +62,7 @@ func TestBandwidthCounter(t *testing.T) {
bwc := NewBandwidthCounter()
for i := 0; i < 40; i++ {
for i := 0; i < 100; i++ {
p := peer.ID(fmt.Sprintf("peer-%d", i))
p := test.MustPeerIDFromSeed(fmt.Sprintf("peer-%d", i))
for j := 0; j < 2; j++ {
proto := protocol.ID(fmt.Sprintf("proto-%d", j))

Expand Down Expand Up @@ -93,7 +93,7 @@ func TestBandwidthCounter(t *testing.T) {
byPeer := bwc.GetBandwidthByPeer()
require.Len(t, byPeer, 100, "expected 100 peers")
for i := 0; i < 100; i++ {
p := peer.ID(fmt.Sprintf("peer-%d", i))
p := test.MustPeerIDFromSeed(fmt.Sprintf("peer-%d", i))
for _, stats := range [...]Stats{bwc.GetBandwidthForPeer(p), byPeer[p]} {
check(stats)
}
Expand All @@ -118,7 +118,7 @@ func TestBandwidthCounter(t *testing.T) {
func TestResetBandwidthCounter(t *testing.T) {
bwc := NewBandwidthCounter()

p := peer.ID("peer-0")
p := test.MustPeerIDFromSeed("peer-0")
proto := protocol.ID("proto-0")

// We don't calculate bandwidth till we've been active for a second.
Expand Down
2 changes: 1 addition & 1 deletion core/network/rcmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ func (n *NullScope) BeginSpan() (ResourceScopeSpan, error) { return &NullScop
func (n *NullScope) Done() {}
func (n *NullScope) Name() string { return "" }
func (n *NullScope) Protocol() protocol.ID { return "" }
func (n *NullScope) Peer() peer.ID { return "" }
func (n *NullScope) Peer() peer.ID { return peer.EmptyID }
func (n *NullScope) PeerScope() PeerScope { return &NullScope{} }
func (n *NullScope) SetPeer(peer.ID) error { return nil }
func (n *NullScope) ProtocolScope() ProtocolScope { return &NullScope{} }
Expand Down
10 changes: 5 additions & 5 deletions core/peer/addrinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func AddrInfosFromP2pAddrs(maddrs ...ma.Multiaddr) ([]AddrInfo, error) {
m := make(map[ID][]ma.Multiaddr)
for _, maddr := range maddrs {
transport, id := SplitAddr(maddr)
if id == "" {
if id == EmptyID {
return nil, ErrInvalidAddr
}
if transport == nil {
Expand All @@ -50,14 +50,14 @@ func AddrInfosFromP2pAddrs(maddrs ...ma.Multiaddr) ([]AddrInfo, error) {
// * Returns a empty peer ID if the address doesn't contain a /p2p part.
func SplitAddr(m ma.Multiaddr) (transport ma.Multiaddr, id ID) {
if m == nil {
return nil, ""
return nil, EmptyID
}

transport, p2ppart := ma.SplitLast(m)
if p2ppart == nil || p2ppart.Protocol().Code != ma.P_P2P {
return m, ""
return m, EmptyID
}
id = ID(p2ppart.RawValue()) // already validated by the multiaddr library.
id = ID{idBytes: string(p2ppart.RawValue())} // already validated by the multiaddr library.
return transport, id
}

Expand All @@ -74,7 +74,7 @@ func AddrInfoFromString(s string) (*AddrInfo, error) {
// AddrInfoFromP2pAddr converts a Multiaddr to an AddrInfo.
func AddrInfoFromP2pAddr(m ma.Multiaddr) (*AddrInfo, error) {
transport, id := SplitAddr(m)
if id == "" {
if id == EmptyID {
return nil, ErrInvalidAddr
}
info := &AddrInfo{ID: id}
Expand Down
2 changes: 1 addition & 1 deletion core/peer/addrinfo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ func TestSplitAddr(t *testing.T) {
if !tpt.Equal(maddrTpt) {
t.Fatal("expected a transport")
}
if id != "" {
if id != EmptyID {
t.Fatal("expected no peer ID")
}
}
Expand Down
35 changes: 20 additions & 15 deletions core/peer/peer.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ const maxInlineKeyLength = 42
//
// Peer IDs are derived by hashing a peer's public key and encoding the
// hash output as a multihash. See IDFromPublicKey for details.
type ID string
type ID struct {
// the raw bytes for the id. This is a string type so that we can compare them
idBytes string
}

var EmptyID = ID{}

// Pretty returns a base58-encoded string representation of the ID.
// Deprecated: use String() instead.
Expand All @@ -55,7 +60,7 @@ func (id ID) Loggable() map[string]interface{} {
}

func (id ID) String() string {
return b58.Encode([]byte(id))
return b58.Encode([]byte(id.idBytes))
}

// ShortString prints out the peer ID.
Expand Down Expand Up @@ -91,7 +96,7 @@ func (id ID) MatchesPublicKey(pk ic.PubKey) bool {
// This method returns ErrNoPublicKey if the peer ID looks valid but it can't extract
// the public key.
func (id ID) ExtractPublicKey() (ic.PubKey, error) {
decoded, err := mh.Decode([]byte(id))
decoded, err := mh.Decode([]byte(id.idBytes))
if err != nil {
return nil, err
}
Expand All @@ -107,7 +112,7 @@ func (id ID) ExtractPublicKey() (ic.PubKey, error) {

// Validate checks if ID is empty or not.
func (id ID) Validate() error {
if id == ID("") {
if id == EmptyID {
return ErrEmptyPeerID
}

Expand All @@ -118,9 +123,9 @@ func (id ID) Validate() error {
// the value to make sure it is a multihash.
func IDFromBytes(b []byte) (ID, error) {
if _, err := mh.Cast(b); err != nil {
return ID(""), err
return EmptyID, err
}
return ID(b), nil
return ID{idBytes: string(b)}, nil
}

// Decode accepts an encoded peer ID and returns the decoded ID if the input is
Expand All @@ -133,14 +138,14 @@ func Decode(s string) (ID, error) {
// 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 EmptyID, fmt.Errorf("failed to parse peer ID: %s", err)
}
return ID(m), nil
return ID{idBytes: string(m)}, nil
}

c, err := cid.Decode(s)
if err != nil {
return "", fmt.Errorf("failed to parse peer ID: %s", err)
return EmptyID, fmt.Errorf("failed to parse peer ID: %s", err)
}
return FromCid(c)
}
Expand All @@ -159,16 +164,16 @@ func Encode(id ID) string {
func FromCid(c cid.Cid) (ID, error) {
code := mc.Code(c.Type())
if code != mc.Libp2pKey {
return "", fmt.Errorf("can't convert CID of type %q to a peer ID", code)
return EmptyID, fmt.Errorf("can't convert CID of type %q to a peer ID", code)
}
return ID(c.Hash()), nil
return ID{idBytes: string(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))
m, err := mh.Cast([]byte(id.idBytes))
if err != nil {
return cid.Cid{}
}
Expand All @@ -179,14 +184,14 @@ func ToCid(id ID) cid.Cid {
func IDFromPublicKey(pk ic.PubKey) (ID, error) {
b, err := ic.MarshalPublicKey(pk)
if err != nil {
return "", err
return EmptyID, err
}
var alg uint64 = mh.SHA2_256
if AdvancedEnableInlining && len(b) <= maxInlineKeyLength {
alg = mh.IDENTITY
}
hash, _ := mh.Sum(b, alg, -1)
return ID(hash), nil
return ID{idBytes: string(hash)}, nil
}

// IDFromPrivateKey returns the Peer ID corresponding to the secret key sk.
Expand All @@ -199,7 +204,7 @@ type IDSlice []ID

func (es IDSlice) Len() int { return len(es) }
func (es IDSlice) Swap(i, j int) { es[i], es[j] = es[j], es[i] }
func (es IDSlice) Less(i, j int) bool { return string(es[i]) < string(es[j]) }
func (es IDSlice) Less(i, j int) bool { return es[i].idBytes < es[j].idBytes }

func (es IDSlice) String() string {
peersStrings := make([]string, len(es))
Expand Down
11 changes: 8 additions & 3 deletions core/peer/peer_serde.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,21 @@ var _ encoding.TextMarshaler = (*ID)(nil)
var _ encoding.TextUnmarshaler = (*ID)(nil)

func (id ID) Marshal() ([]byte, error) {
return []byte(id), nil
return []byte(id.idBytes), nil
}

// MarshalBinary returns the byte representation of the peer ID.
func (id ID) MarshalBinary() ([]byte, error) {
return id.Marshal()
}

// MustMarshalBinary returns the byte representation of the peer ID.
func (id ID) MustMarshalBinary() []byte {
return []byte(id.idBytes)
}

func (id ID) MarshalTo(data []byte) (n int, err error) {
return copy(data, []byte(id)), nil
return copy(data, []byte(id.idBytes)), nil
}

func (id *ID) Unmarshal(data []byte) (err error) {
Expand All @@ -41,7 +46,7 @@ func (id *ID) UnmarshalBinary(data []byte) error {
}

func (id ID) Size() int {
return len([]byte(id))
return len([]byte(id.idBytes))
}

func (id ID) MarshalJSON() ([]byte, error) {
Expand Down
12 changes: 6 additions & 6 deletions core/peer/peer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ func TestIDMatchesPublicKey(t *testing.T) {
t.Fatal(err)
}

if ks.hpk != string(p1) {
if ks.hpk != string(p1.MustMarshalBinary()) {
t.Error("p1 and hpk differ")
}

Expand Down Expand Up @@ -129,7 +129,7 @@ func TestIDMatchesPrivateKey(t *testing.T) {
t.Fatal(err)
}

if ks.hpk != string(p1) {
if ks.hpk != string(p1.MustMarshalBinary()) {
t.Error("p1 and hpk differ")
}

Expand Down Expand Up @@ -159,7 +159,7 @@ func TestIDEncoding(t *testing.T) {
t.Fatal(err)
}

if ks.hpk != string(p1) {
if ks.hpk != string(p1.MustMarshalBinary()) {
t.Error("p1 and hpk differ")
}

Expand Down Expand Up @@ -191,7 +191,7 @@ func TestIDEncoding(t *testing.T) {
t.Fatal("should refuse to decode a non-peer ID CID")
}

c := ToCid("")
c := ToCid(EmptyID)
if c.Defined() {
t.Fatal("cid of empty peer ID should have been undefined")
}
Expand Down Expand Up @@ -222,7 +222,7 @@ func TestPublicKeyExtraction(t *testing.T) {
}

// Test invalid multihash (invariant of the type of public key)
pk, err := ID("").ExtractPublicKey()
pk, err := EmptyID.ExtractPublicKey()
if err == nil {
t.Fatal("expected an error")
}
Expand Down Expand Up @@ -251,7 +251,7 @@ func TestPublicKeyExtraction(t *testing.T) {

func TestValidate(t *testing.T) {
// Empty peer ID invalidates
err := ID("").Validate()
err := EmptyID.Validate()
if err == nil {
t.Error("expected error")
} else if err != ErrEmptyPeerID {
Expand Down
2 changes: 1 addition & 1 deletion core/routing/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ type PubKeyFetcher interface {
// KeyForPublicKey returns the key used to retrieve public keys
// from a value store.
func KeyForPublicKey(id peer.ID) string {
return "/pk/" + string(id)
return "/pk/" + id.String()
}

// GetPublicKey retrieves the public key associated with the given peer ID from
Expand Down
4 changes: 2 additions & 2 deletions core/sec/insecure/insecure.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (t *Transport) SecureInbound(ctx context.Context, insecure net.Conn, p peer
return nil, err
}

if t.key != nil && p != "" && p != conn.remote {
if t.key != nil && p != peer.EmptyID && p != conn.remote {
return nil, fmt.Errorf("remote peer sent unexpected peer ID. expected=%s received=%s", p, conn.remote)
}

Expand Down Expand Up @@ -143,7 +143,7 @@ func makeExchangeMessage(pubkey ci.PubKey) (*pb.Exchange, error) {
}

return &pb.Exchange{
Id: []byte(id),
Id: id.MustMarshalBinary(),
Pubkey: keyMsg,
}, nil
}
Expand Down
Loading