Skip to content

Commit 323ee8e

Browse files
authored
Merge pull request #420 from libp2p/fix/add-when-empty
fix: try to re-add existing peers when the routing table is empty
2 parents 85ccd07 + 3c3e567 commit 323ee8e

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

dht_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,79 @@ func TestRefreshBelowMinRTThreshold(t *testing.T) {
757757
assert.Equal(t, dhtE.self, dhtA.routingTable.Find(dhtE.self), "A's routing table should have peer E!")
758758
}
759759

760+
// Check to make sure we re-fill the routing table from connected peers when it
761+
// completely empties.
762+
func TestEmptyTable(t *testing.T) {
763+
ctx, cancel := context.WithCancel(context.Background())
764+
defer cancel()
765+
766+
nDHTs := 50 // needs more than 40 peers so we don't add all of them to our routing table.
767+
dhts := setupDHTS(t, ctx, nDHTs)
768+
defer func() {
769+
for _, dht := range dhts {
770+
dht.Close()
771+
defer dht.host.Close()
772+
}
773+
}()
774+
775+
t.Logf("dhts are not connected. %d", nDHTs)
776+
for _, dht := range dhts {
777+
rtlen := dht.routingTable.Size()
778+
if rtlen > 0 {
779+
t.Errorf("routing table for %s should have 0 peers. has %d", dht.self, rtlen)
780+
}
781+
}
782+
783+
for i := 1; i < nDHTs; i++ {
784+
connectNoSync(t, ctx, dhts[0], dhts[i])
785+
}
786+
787+
// Wait till the routing table stabilizes.
788+
oldSize := dhts[0].routingTable.Size()
789+
for {
790+
time.Sleep(time.Millisecond)
791+
newSize := dhts[0].routingTable.Size()
792+
if oldSize == newSize {
793+
break
794+
}
795+
oldSize = newSize
796+
}
797+
798+
if u.Debug {
799+
printRoutingTables(dhts[:1])
800+
}
801+
802+
// Disconnect from all peers that _were_ in the routing table.
803+
routingTablePeers := make(map[peer.ID]bool, nDHTs)
804+
for _, p := range dhts[0].RoutingTable().ListPeers() {
805+
routingTablePeers[p] = true
806+
}
807+
808+
oldDHTs := dhts[1:]
809+
dhts = dhts[:1]
810+
for _, dht := range oldDHTs {
811+
if routingTablePeers[dht.Host().ID()] {
812+
dhts[0].Host().Network().ClosePeer(dht.host.ID())
813+
dht.Close()
814+
dht.host.Close()
815+
} else {
816+
dhts = append(dhts, dht)
817+
}
818+
}
819+
820+
// we should now _re-add_ some peers to the routing table
821+
for i := 0; i < 100; i++ {
822+
if dhts[0].routingTable.Size() > 0 {
823+
return
824+
}
825+
time.Sleep(time.Millisecond)
826+
}
827+
if u.Debug {
828+
printRoutingTables(dhts[:1])
829+
}
830+
t.Fatal("routing table shouldn't have been empty")
831+
}
832+
760833
func TestPeriodicRefresh(t *testing.T) {
761834
if ci.IsRunning() {
762835
t.Skip("skipping on CI. highly timing dependent")

notif.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ func (nn *netNotifiee) Disconnected(n network.Network, v network.Conn) {
109109
}
110110

111111
dht.routingTable.Remove(p)
112+
if dht.routingTable.Size() < minRTRefreshThreshold {
113+
// TODO: Actively bootstrap. For now, just try to add the currently connected peers.
114+
for _, p := range dht.host.Network().Peers() {
115+
// Don't bother probing, we do that on connect.
116+
protos, err := dht.peerstore.SupportsProtocols(p, dht.protocolStrs()...)
117+
if err == nil && len(protos) != 0 {
118+
dht.Update(dht.Context(), p)
119+
}
120+
}
121+
}
112122

113123
dht.smlk.Lock()
114124
defer dht.smlk.Unlock()

0 commit comments

Comments
 (0)