diff --git a/swarm/network/kademlia.go b/swarm/network/kademlia.go index c98192bf2b..bbac883963 100644 --- a/swarm/network/kademlia.go +++ b/swarm/network/kademlia.go @@ -454,20 +454,32 @@ func (k *Kademlia) neighbourhoodDepth() (depth int) { } var size int var b bool + var lastPo int f := func(v pot.Val, i int) bool { size++ + + // the actual depth of the farthest nn if size == k.MinProxBinSize { b = true depth = i return true } + + // if there are empty bins between farthest nn and current node, the depth should be the farthest of those empty bins if b && i < depth { depth = i + 1 + lastPo = i return false } + lastPo = i return true } k.conns.EachNeighbour(k.base, pof, f) + + // cover edge case where more than one farthest nn and only proxpeers + if lastPo == depth { + depth = 0 + } return depth } diff --git a/swarm/network/kademlia_test.go b/swarm/network/kademlia_test.go index a4dd322cc4..73dc8581b6 100644 --- a/swarm/network/kademlia_test.go +++ b/swarm/network/kademlia_test.go @@ -76,7 +76,7 @@ func Register(k *Kademlia, regs ...string) { } } -func TestNeighborhoodDepth(t *testing.T) { +func TestNeighbourhoodDepth(t *testing.T) { baseAddressBytes := RandomAddr().OAddr kad := NewKademlia(baseAddressBytes, NewKadParams()) @@ -103,7 +103,7 @@ func TestNeighborhoodDepth(t *testing.T) { kad.On(midPeer) depth = kad.NeighbourhoodDepth() if depth != 5 { - t.Fatalf("expected depth 4, was %d", depth) + t.Fatalf("expected depth 5, was %d", depth) } kad.Off(midPeer) @@ -119,6 +119,24 @@ func TestNeighborhoodDepth(t *testing.T) { if depth != 2 { t.Fatalf("expected depth 2, was %d", depth) } + + midSameAddress := pot.RandomAddressAt(baseAddress, 4) + midSamePeer := newTestDiscoveryPeer(midSameAddress, kad) + kad.Off(closerPeer) + kad.On(midPeer) + kad.On(midSamePeer) + depth = kad.NeighbourhoodDepth() + if depth != 2 { + t.Fatalf("expected depth 2, was %d", depth) + } + + kad.Off(fartherPeer) + log.Trace(kad.string()) + time.Sleep(time.Millisecond) + depth = kad.NeighbourhoodDepth() + if depth != 0 { + t.Fatalf("expected depth 0, was %d", depth) + } } func testSuggestPeer(k *Kademlia, expAddr string, expPo int, expWant bool) error {