diff --git a/p2p/host/peerstore/interface.go b/p2p/host/peerstore/interface.go index e3d988cee7..105dedc71a 100644 --- a/p2p/host/peerstore/interface.go +++ b/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 diff --git a/p2p/host/peerstore/metrics.go b/p2p/host/peerstore/metrics.go index 05b867692b..f6d0ccb56e 100644 --- a/p2p/host/peerstore/metrics.go +++ b/p2p/host/peerstore/metrics.go @@ -4,6 +4,7 @@ import ( "sync" "time" + moved "github.com/libp2p/go-libp2p-core/peerstore" "github.com/libp2p/go-libp2p-peer" ) @@ -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 diff --git a/p2p/host/peerstore/peerinfo.go b/p2p/host/peerstore/peerinfo.go index 6adaa20391..24c8c31f3a 100644 --- a/p2p/host/peerstore/peerinfo.go +++ b/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) } diff --git a/p2p/host/peerstore/peerinfo_test.go b/p2p/host/peerstore/peerinfo_test.go deleted file mode 100644 index 336c719b03..0000000000 --- a/p2p/host/peerstore/peerinfo_test.go +++ /dev/null @@ -1,232 +0,0 @@ -package peerstore - -import ( - "encoding/json" - "testing" - - "github.com/libp2p/go-libp2p-peer" - ma "github.com/multiformats/go-multiaddr" -) - -func mustAddr(t *testing.T, s string) ma.Multiaddr { - addr, err := ma.NewMultiaddr(s) - if err != nil { - t.Fatal(err) - } - - return addr -} - -func TestPeerInfoMarshal(t *testing.T) { - a := mustAddr(t, "/ip4/1.2.3.4/tcp/4536") - b := mustAddr(t, "/ip4/1.2.3.8/udp/7777") - id, err := peer.IDB58Decode("QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ") - if err != nil { - t.Fatal(err) - } - - pi := &PeerInfo{ - ID: id, - Addrs: []ma.Multiaddr{a, b}, - } - - data, err := pi.MarshalJSON() - if err != nil { - t.Fatal(err) - } - - pi2 := new(PeerInfo) - if err := pi2.UnmarshalJSON(data); err != nil { - t.Fatal(err) - } - - if pi2.ID != pi.ID { - t.Fatal("ids didnt match after marshal") - } - - if !pi.Addrs[0].Equal(pi2.Addrs[0]) { - t.Fatal("wrong addrs") - } - - if !pi.Addrs[1].Equal(pi2.Addrs[1]) { - t.Fatal("wrong addrs") - } - - lgbl := pi2.Loggable() - if lgbl["peerID"] != id.Pretty() { - t.Fatal("loggables gave wrong peerID output") - } -} - -func TestPeerInfoMarshalWithPointer(t *testing.T) { - a := mustAddr(t, "/ip4/1.2.3.4/tcp/4536") - b := mustAddr(t, "/ip4/1.2.3.8/udp/7777") - id, err := peer.IDB58Decode("QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ") - if err != nil { - t.Fatal(err) - } - - pi := PeerInfo{ - ID: id, - Addrs: []ma.Multiaddr{a, b}, - } - - data, err := json.Marshal(&pi) - if err != nil { - t.Fatal(err) - } - - pi2 := new(PeerInfo) - if err := json.Unmarshal(data, pi2); err != nil { - t.Fatal(err) - } - - if pi2.ID != pi.ID { - t.Fatal("ids didnt match after marshal") - } - - if !pi.Addrs[0].Equal(pi2.Addrs[0]) { - t.Fatal("wrong addrs") - } - - if !pi.Addrs[1].Equal(pi2.Addrs[1]) { - t.Fatal("wrong addrs") - } - - lgbl := pi2.Loggable() - if lgbl["peerID"] != id.Pretty() { - t.Fatal("loggables gave wrong peerID output") - } -} - -func TestPeerInfoMarshalWithValue(t *testing.T) { - a := mustAddr(t, "/ip4/1.2.3.4/tcp/4536") - b := mustAddr(t, "/ip4/1.2.3.8/udp/7777") - id, err := peer.IDB58Decode("QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ") - if err != nil { - t.Fatal(err) - } - - pi := PeerInfo{ - ID: id, - Addrs: []ma.Multiaddr{a, b}, - } - - data, err := json.Marshal(pi) - if err != nil { - t.Fatal(err) - } - - pi2 := new(PeerInfo) - if err := json.Unmarshal(data, pi2); err != nil { - t.Fatal(err) - } - - if pi2.ID != pi.ID { - t.Fatal("ids didnt match after marshal") - } - - if !pi.Addrs[0].Equal(pi2.Addrs[0]) { - t.Fatal("wrong addrs") - } - - if !pi.Addrs[1].Equal(pi2.Addrs[1]) { - t.Fatal("wrong addrs") - } - - lgbl := pi2.Loggable() - if lgbl["peerID"] != id.Pretty() { - t.Fatal("loggables gave wrong peerID output") - } -} - -func TestP2pAddrParsing(t *testing.T) { - id, err := peer.IDB58Decode("QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ") - if err != nil { - t.Error(err) - } - addr := ma.StringCast("/ip4/1.2.3.4/tcp/4536") - p2paddr := ma.Join(addr, ma.StringCast("/ipfs/"+peer.IDB58Encode(id))) - - pinfo, err := InfoFromP2pAddr(p2paddr) - if err != nil { - t.Error(err) - } - - if pinfo.ID != id { - t.Fatalf("expected PeerID [%s], got [%s]", id, pinfo.ID) - } - - if len(pinfo.Addrs) != 1 { - t.Fatalf("expected 1 addr, got %d", len(pinfo.Addrs)) - } - - if !addr.Equal(pinfo.Addrs[0]) { - t.Fatalf("expected addr [%s], got [%s]", addr, pinfo.Addrs[0]) - } - - addr = ma.StringCast("/ipfs/" + peer.IDB58Encode(id)) - pinfo, err = InfoFromP2pAddr(addr) - if err != nil { - t.Error(err) - } - - if pinfo.ID != id { - t.Fatalf("expected PeerID [%s], got [%s]", id, pinfo.ID) - } - - if len(pinfo.Addrs) > 0 { - t.Fatalf("expected 0 addrs, got %d", len(pinfo.Addrs)) - } - - addr = ma.StringCast("/ip4/1.2.3.4/tcp/4536") - pinfo, err = InfoFromP2pAddr(addr) - if err == nil { - t.Fatalf("expected error, got none") - } - - addr = ma.StringCast("/ip4/1.2.3.4/tcp/4536/http") - pinfo, err = InfoFromP2pAddr(addr) - if err == nil { - t.Fatalf("expected error, got none") - } -} - -func TestP2pAddrConstruction(t *testing.T) { - id, err := peer.IDB58Decode("QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ") - if err != nil { - t.Error(err) - } - addr := ma.StringCast("/ip4/1.2.3.4/tcp/4536") - p2paddr := ma.Join(addr, ma.StringCast("/ipfs/"+peer.IDB58Encode(id))) - - pi := &PeerInfo{ID: id, Addrs: []ma.Multiaddr{addr}} - p2paddrs, err := InfoToP2pAddrs(pi) - if err != nil { - t.Error(err) - } - - if len(p2paddrs) != 1 { - t.Fatalf("expected 1 addr, got %d", len(p2paddrs)) - } - - if !p2paddr.Equal(p2paddrs[0]) { - t.Fatalf("expected [%s], got [%s]", p2paddr, p2paddrs[0]) - } - - pi = &PeerInfo{ID: id} - p2paddrs, err = InfoToP2pAddrs(pi) - if err != nil { - t.Error(err) - } - - if len(p2paddrs) > 0 { - t.Fatalf("expected 0 addrs, got %d", len(p2paddrs)) - } - - pi = &PeerInfo{Addrs: []ma.Multiaddr{ma.StringCast("/ip4/1.2.3.4/tcp/4536")}} - _, err = InfoToP2pAddrs(pi) - if err == nil { - t.Fatalf("expected error, got none") - } -}