mirror of
https://github.com/fluencelabs/go-libp2p-kad-dht
synced 2025-04-24 22:32:13 +00:00
fix: try to re-add existing peers when the routing table is empty
Otherwise, we could decide to _not_ add a peer, disconnect from most peers, and be unable to query the DHT even if we're technically connected to a peer in the DHT.
This commit is contained in:
parent
85ccd076a8
commit
3c3e567143
73
dht_test.go
73
dht_test.go
@ -757,6 +757,79 @@ func TestRefreshBelowMinRTThreshold(t *testing.T) {
|
||||
assert.Equal(t, dhtE.self, dhtA.routingTable.Find(dhtE.self), "A's routing table should have peer E!")
|
||||
}
|
||||
|
||||
// Check to make sure we re-fill the routing table from connected peers when it
|
||||
// completely empties.
|
||||
func TestEmptyTable(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
nDHTs := 50 // needs more than 40 peers so we don't add all of them to our routing table.
|
||||
dhts := setupDHTS(t, ctx, nDHTs)
|
||||
defer func() {
|
||||
for _, dht := range dhts {
|
||||
dht.Close()
|
||||
defer dht.host.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
t.Logf("dhts are not connected. %d", nDHTs)
|
||||
for _, dht := range dhts {
|
||||
rtlen := dht.routingTable.Size()
|
||||
if rtlen > 0 {
|
||||
t.Errorf("routing table for %s should have 0 peers. has %d", dht.self, rtlen)
|
||||
}
|
||||
}
|
||||
|
||||
for i := 1; i < nDHTs; i++ {
|
||||
connectNoSync(t, ctx, dhts[0], dhts[i])
|
||||
}
|
||||
|
||||
// Wait till the routing table stabilizes.
|
||||
oldSize := dhts[0].routingTable.Size()
|
||||
for {
|
||||
time.Sleep(time.Millisecond)
|
||||
newSize := dhts[0].routingTable.Size()
|
||||
if oldSize == newSize {
|
||||
break
|
||||
}
|
||||
oldSize = newSize
|
||||
}
|
||||
|
||||
if u.Debug {
|
||||
printRoutingTables(dhts[:1])
|
||||
}
|
||||
|
||||
// Disconnect from all peers that _were_ in the routing table.
|
||||
routingTablePeers := make(map[peer.ID]bool, nDHTs)
|
||||
for _, p := range dhts[0].RoutingTable().ListPeers() {
|
||||
routingTablePeers[p] = true
|
||||
}
|
||||
|
||||
oldDHTs := dhts[1:]
|
||||
dhts = dhts[:1]
|
||||
for _, dht := range oldDHTs {
|
||||
if routingTablePeers[dht.Host().ID()] {
|
||||
dhts[0].Host().Network().ClosePeer(dht.host.ID())
|
||||
dht.Close()
|
||||
dht.host.Close()
|
||||
} else {
|
||||
dhts = append(dhts, dht)
|
||||
}
|
||||
}
|
||||
|
||||
// we should now _re-add_ some peers to the routing table
|
||||
for i := 0; i < 100; i++ {
|
||||
if dhts[0].routingTable.Size() > 0 {
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Millisecond)
|
||||
}
|
||||
if u.Debug {
|
||||
printRoutingTables(dhts[:1])
|
||||
}
|
||||
t.Fatal("routing table shouldn't have been empty")
|
||||
}
|
||||
|
||||
func TestPeriodicRefresh(t *testing.T) {
|
||||
if ci.IsRunning() {
|
||||
t.Skip("skipping on CI. highly timing dependent")
|
||||
|
10
notif.go
10
notif.go
@ -109,6 +109,16 @@ func (nn *netNotifiee) Disconnected(n network.Network, v network.Conn) {
|
||||
}
|
||||
|
||||
dht.routingTable.Remove(p)
|
||||
if dht.routingTable.Size() < minRTRefreshThreshold {
|
||||
// TODO: Actively bootstrap. For now, just try to add the currently connected peers.
|
||||
for _, p := range dht.host.Network().Peers() {
|
||||
// Don't bother probing, we do that on connect.
|
||||
protos, err := dht.peerstore.SupportsProtocols(p, dht.protocolStrs()...)
|
||||
if err == nil && len(protos) != 0 {
|
||||
dht.Update(dht.Context(), p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dht.smlk.Lock()
|
||||
defer dht.smlk.Unlock()
|
||||
|
Loading…
x
Reference in New Issue
Block a user