Skip to content

Commit

Permalink
Consolidate abstractions and core types into go-libp2p-core (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
raulk committed May 23, 2019
1 parent ff02b44 commit 075e2a2
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 476 deletions.
156 changes: 27 additions & 129 deletions p2p/host/peerstore/interface.go
@@ -1,148 +1,46 @@
package peerstore

import (
"context"
"errors"
"io"
"math"
"time"
import core "github.com/libp2p/go-libp2p-core/peerstore"

ic "github.com/libp2p/go-libp2p-crypto"
peer "github.com/libp2p/go-libp2p-peer"
ma "github.com/multiformats/go-multiaddr"
)

var ErrNotFound = errors.New("item not found")
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.ErrNotFound instead.
var ErrNotFound = core.ErrNotFound

var (
// AddressTTL is the expiration time of addresses.
AddressTTL = time.Hour
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.AddressTTL instead.
AddressTTL = core.AddressTTL

// TempAddrTTL is the ttl used for a short lived address
TempAddrTTL = time.Minute * 2
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.TempAddrTTL instead.
TempAddrTTL = core.TempAddrTTL

// ProviderAddrTTL is the TTL of an address we've received from a provider.
// This is also a temporary address, but lasts longer. After this expires,
// the records we return will require an extra lookup.
ProviderAddrTTL = time.Minute * 10
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.ProviderAddrTTL instead.
ProviderAddrTTL = core.ProviderAddrTTL

// RecentlyConnectedAddrTTL is used when we recently connected to a peer.
// It means that we are reasonably certain of the peer's address.
RecentlyConnectedAddrTTL = time.Minute * 10
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.RecentlyConnectedAddrTTL instead.
RecentlyConnectedAddrTTL = core.RecentlyConnectedAddrTTL

// OwnObservedAddrTTL is used for our own external addresses observed by peers.
OwnObservedAddrTTL = time.Minute * 10
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.OwnObservedAddrTTL instead.
OwnObservedAddrTTL = core.OwnObservedAddrTTL
)

// Permanent TTLs (distinct so we can distinguish between them, constant as they
// are, in fact, permanent)
const (
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.PermanentAddrTTL instead.
PermanentAddrTTL = core.PermanentAddrTTL

// PermanentAddrTTL is the ttl for a "permanent address" (e.g. bootstrap nodes).
PermanentAddrTTL = math.MaxInt64 - iota

// ConnectedAddrTTL is the ttl used for the addresses of a peer to whom
// we're connected directly. This is basically permanent, as we will
// clear them + re-add under a TempAddrTTL after disconnecting.
ConnectedAddrTTL
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.ConnectedAddrTTL instead.
ConnectedAddrTTL = core.ConnectedAddrTTL
)

// Peerstore provides a threadsafe store of Peer related
// information.
type Peerstore interface {
io.Closer

AddrBook
KeyBook
PeerMetadata
Metrics
ProtoBook

// PeerInfo returns a peer.PeerInfo struct for given peer.ID.
// This is a small slice of the information Peerstore has on
// that peer, useful to other services.
PeerInfo(peer.ID) PeerInfo

// Peers returns all of the peer IDs stored across all inner stores.
Peers() peer.IDSlice
}

// PeerMetadata can handle values of any type. Serializing values is
// up to the implementation. Dynamic type introspection may not be
// supported, in which case explicitly enlisting types in the
// serializer may be required.
//
// Refer to the docs of the underlying implementation for more
// information.
type PeerMetadata interface {
// Get/Put is a simple registry for other peer-related key/value pairs.
// if we find something we use often, it should become its own set of
// methods. this is a last resort.
Get(p peer.ID, key string) (interface{}, error)
Put(p peer.ID, key string, val interface{}) error
}

// AddrBook holds the multiaddrs of peers.
type AddrBook interface {

// AddAddr calls AddAddrs(p, []ma.Multiaddr{addr}, ttl)
AddAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration)

// AddAddrs gives this AddrBook addresses to use, with a given ttl
// (time-to-live), after which the address is no longer valid.
// If the manager has a longer TTL, the operation is a no-op for that address
AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration)

// SetAddr calls mgr.SetAddrs(p, addr, ttl)
SetAddr(p peer.ID, addr ma.Multiaddr, ttl time.Duration)

// SetAddrs sets the ttl on addresses. This clears any TTL there previously.
// This is used when we receive the best estimate of the validity of an address.
SetAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration)

// UpdateAddrs updates the addresses associated with the given peer that have
// the given oldTTL to have the given newTTL.
UpdateAddrs(p peer.ID, oldTTL time.Duration, newTTL time.Duration)

// Addresses returns all known (and valid) addresses for a given peer
Addrs(p peer.ID) []ma.Multiaddr

// AddrStream returns a channel that gets all addresses for a given
// peer sent on it. If new addresses are added after the call is made
// they will be sent along through the channel as well.
AddrStream(context.Context, peer.ID) <-chan ma.Multiaddr

// ClearAddresses removes all previously stored addresses
ClearAddrs(p peer.ID)

// PeersWithAddrs returns all of the peer IDs stored in the AddrBook
PeersWithAddrs() peer.IDSlice
}

// KeyBook tracks the keys of Peers.
type KeyBook interface {
// PubKey stores the public key of a peer.
PubKey(peer.ID) ic.PubKey

// AddPubKey stores the public key of a peer.
AddPubKey(peer.ID, ic.PubKey) error
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.Peerstore instead.
type Peerstore = core.Peerstore

// PrivKey returns the private key of a peer, if known. Generally this might only be our own
// private key, see
// https://discuss.libp2p.io/t/what-is-the-purpose-of-having-map-peer-id-privatekey-in-peerstore/74.
PrivKey(peer.ID) ic.PrivKey
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.PeerMetadata instead.
type PeerMetadata = core.PeerMetadata

// AddPrivKey stores the private key of a peer.
AddPrivKey(peer.ID, ic.PrivKey) error
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.AddrBook instead.
type AddrBook = core.AddrBook

// PeersWithKeys returns all the peer IDs stored in the KeyBook
PeersWithKeys() peer.IDSlice
}
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.KeyBook instead.
type KeyBook = core.KeyBook

// ProtoBook tracks the protocols supported by peers
type ProtoBook interface {
GetProtocols(peer.ID) ([]string, error)
AddProtocols(peer.ID, ...string) error
SetProtocols(peer.ID, ...string) error
SupportsProtocols(peer.ID, ...string) ([]string, error)
}
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.ProtoBook instead.
type ProtoBook = core.ProtoBook
14 changes: 3 additions & 11 deletions p2p/host/peerstore/metrics.go
Expand Up @@ -4,6 +4,7 @@ import (
"sync"
"time"

moved "github.com/libp2p/go-libp2p-core/peerstore"
"github.com/libp2p/go-libp2p-peer"
)

Expand All @@ -12,17 +13,8 @@ import (
// 1 is 100% change, 0 is no change.
var LatencyEWMASmoothing = 0.1

// Metrics is just an object that tracks metrics
// across a set of peers.
type Metrics interface {

// RecordLatency records a new latency measurement
RecordLatency(peer.ID, time.Duration)

// LatencyEWMA returns an exponentially-weighted moving avg.
// of all measurements of a peer's latency.
LatencyEWMA(peer.ID) time.Duration
}
// Deprecated: use github.com/libp2p/go-libp2p-core/peerstore.Metrics instead.
type Metrics = moved.Metrics

type metrics struct {
latmap map[peer.ID]time.Duration
Expand Down
115 changes: 11 additions & 104 deletions p2p/host/peerstore/peerinfo.go
@@ -1,115 +1,22 @@
package peerstore

import (
"encoding/json"
"fmt"
"strings"

peer "github.com/libp2p/go-libp2p-peer"
core "github.com/libp2p/go-libp2p-core/peer"
ma "github.com/multiformats/go-multiaddr"
)

// PeerInfo is a small struct used to pass around a peer with
// a set of addresses (and later, keys?). This is not meant to be
// a complete view of the system, but rather to model updates to
// the peerstore. It is used by things like the routing system.
type PeerInfo struct {
ID peer.ID
Addrs []ma.Multiaddr
}

var _ fmt.Stringer = PeerInfo{}

func (pi PeerInfo) String() string {
return fmt.Sprintf("{%v: %v}", pi.ID, pi.Addrs)
}

var ErrInvalidAddr = fmt.Errorf("invalid p2p multiaddr")

func InfoFromP2pAddr(m ma.Multiaddr) (*PeerInfo, error) {
if m == nil {
return nil, ErrInvalidAddr
}

// make sure it's an IPFS addr
parts := ma.Split(m)
if len(parts) < 1 {
return nil, ErrInvalidAddr
}
// Deprecated: use github.com/libp2p/go-libp2p-core/peer.Info instead.
type PeerInfo = core.AddrInfo

// TODO(lgierth): we shouldn't assume /ipfs is the last part
ipfspart := parts[len(parts)-1]
if ipfspart.Protocols()[0].Code != ma.P_IPFS {
return nil, ErrInvalidAddr
}

// make sure the /ipfs value parses as a peer.ID
peerIdParts := strings.Split(ipfspart.String(), "/")
peerIdStr := peerIdParts[len(peerIdParts)-1]
id, err := peer.IDB58Decode(peerIdStr)
if err != nil {
return nil, err
}

// we might have received just an /ipfs part, which means there's no addr.
var addrs []ma.Multiaddr
if len(parts) > 1 {
addrs = append(addrs, ma.Join(parts[:len(parts)-1]...))
}

return &PeerInfo{
ID: id,
Addrs: addrs,
}, nil
}

func InfoToP2pAddrs(pi *PeerInfo) ([]ma.Multiaddr, error) {
var addrs []ma.Multiaddr
tpl := "/" + ma.ProtocolWithCode(ma.P_IPFS).Name + "/"
for _, addr := range pi.Addrs {
p2paddr, err := ma.NewMultiaddr(tpl + peer.IDB58Encode(pi.ID))
if err != nil {
return nil, err
}
addrs = append(addrs, addr.Encapsulate(p2paddr))
}
return addrs, nil
}

func (pi *PeerInfo) Loggable() map[string]interface{} {
return map[string]interface{}{
"peerID": pi.ID.Pretty(),
"addrs": pi.Addrs,
}
}
// Deprecated: use github.com/libp2p/go-libp2p-core/peer.ErrInvalidAddr instead.
var ErrInvalidAddr = core.ErrInvalidAddr

func (pi PeerInfo) MarshalJSON() ([]byte, error) {
out := make(map[string]interface{})
out["ID"] = pi.ID.Pretty()
var addrs []string
for _, a := range pi.Addrs {
addrs = append(addrs, a.String())
}
out["Addrs"] = addrs
return json.Marshal(out)
// Deprecated: use github.com/libp2p/go-libp2p-core/peer.AddrInfoFromP2pAddr instead.
func InfoFromP2pAddr(m ma.Multiaddr) (*core.AddrInfo, error) {
return core.AddrInfoFromP2pAddr(m)
}

func (pi *PeerInfo) UnmarshalJSON(b []byte) error {
var data map[string]interface{}
err := json.Unmarshal(b, &data)
if err != nil {
return err
}
pid, err := peer.IDB58Decode(data["ID"].(string))
if err != nil {
return err
}
pi.ID = pid
addrs, ok := data["Addrs"].([]interface{})
if ok {
for _, a := range addrs {
pi.Addrs = append(pi.Addrs, ma.StringCast(a.(string)))
}
}
return nil
// Deprecated: use github.com/libp2p/go-libp2p-core/peer.AddrInfoToP2pAddrs instead.
func InfoToP2pAddrs(pi *core.AddrInfo) ([]ma.Multiaddr, error) {
return core.AddrInfoToP2pAddrs(pi)
}

0 comments on commit 075e2a2

Please sign in to comment.