do not mark the routing table as updated after a FindPeer query. bootstrap logic now uses GetClosestPeers instead of FindPeer. FindPeer can return addresses even if not Connected as long as it was either recently connected (CanConnect) or was discovered during the lookup.

This commit is contained in:
Adin Schmahmann 2020-03-24 02:01:06 -04:00
parent 11d4d73729
commit 15e343b8b0
2 changed files with 16 additions and 20 deletions

View File

@ -8,7 +8,6 @@ import (
multierror "github.com/hashicorp/go-multierror" multierror "github.com/hashicorp/go-multierror"
process "github.com/jbenet/goprocess" process "github.com/jbenet/goprocess"
processctx "github.com/jbenet/goprocess/context" processctx "github.com/jbenet/goprocess/context"
"github.com/libp2p/go-libp2p-core/routing"
kbucket "github.com/libp2p/go-libp2p-kbucket" kbucket "github.com/libp2p/go-libp2p-kbucket"
"github.com/multiformats/go-multiaddr" "github.com/multiformats/go-multiaddr"
_ "github.com/multiformats/go-multiaddr-dns" _ "github.com/multiformats/go-multiaddr-dns"
@ -58,8 +57,8 @@ func (dht *IpfsDHT) startSelfLookup() error {
// Do a self walk // Do a self walk
queryCtx, cancel := context.WithTimeout(ctx, dht.rtRefreshQueryTimeout) queryCtx, cancel := context.WithTimeout(ctx, dht.rtRefreshQueryTimeout)
_, err := dht.FindPeer(queryCtx, dht.self) _, err := dht.GetClosestPeers(queryCtx, string(dht.self))
if err == routing.ErrNotFound || err == kbucket.ErrLookupFailure { if err == kbucket.ErrLookupFailure {
err = nil err = nil
} else if err != nil { } else if err != nil {
err = fmt.Errorf("failed to query self during routing table refresh: %s", err) err = fmt.Errorf("failed to query self during routing table refresh: %s", err)
@ -207,10 +206,7 @@ func (dht *IpfsDHT) refreshCpls(ctx context.Context) error {
// walk to the generated peer // walk to the generated peer
walkFnc := func(c context.Context) error { walkFnc := func(c context.Context) error {
_, err := dht.FindPeer(c, randPeer) _, err := dht.GetClosestPeers(c, string(randPeer))
if err == routing.ErrNotFound {
return nil
}
return err return err
} }

View File

@ -5,6 +5,7 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/network"
"github.com/libp2p/go-libp2p-kad-dht/qpeerset"
"sync" "sync"
"time" "time"
@ -688,22 +689,21 @@ func (dht *IpfsDHT) FindPeer(ctx context.Context, id peer.ID) (_ peer.AddrInfo,
return peer.AddrInfo{}, err return peer.AddrInfo{}, err
} }
// refresh the cpl for this key if we discovered the peer because of the query dialedPeerDuringQuery := false
if ctx.Err() == nil { for i, p := range lookupRes.peers {
discoveredPeerDuringQuery := false if p == id {
for _, p := range lookupRes.peers { // Note: we consider PeerUnreachable to be a valid state because the peer may not support the DHT protocol
if p == id { // and therefore the peer would fail the query. The fact that a peer that is returned can be a non-DHT
discoveredPeerDuringQuery = true // server peer and is not identified as such is a bug.
break dialedPeerDuringQuery = lookupRes.state[i] != qpeerset.PeerHeard
} break
}
if discoveredPeerDuringQuery || lookupRes.completed {
dht.routingTable.ResetCplRefreshedAtForID(kb.ConvertPeerID(id), time.Now())
} }
} }
// TODO: Consider unlucky disconnect timing and potentially utilizing network.CanConnect or something similar // Return peer information if we tried to dial the peer during the query or we are (or recently were) connected
if dht.host.Network().Connectedness(id) == network.Connected { // to the peer.
connectedness := dht.host.Network().Connectedness(id)
if dialedPeerDuringQuery || connectedness == network.Connected || connectedness == network.CanConnect {
return dht.peerstore.PeerInfo(id), nil return dht.peerstore.PeerInfo(id), nil
} }