diff --git a/swarm/network/kademlia.go b/swarm/network/kademlia.go index a8ecaa4be4..f41861de9b 100644 --- a/swarm/network/kademlia.go +++ b/swarm/network/kademlia.go @@ -447,12 +447,7 @@ func depthForPot(p *pot.Pot, minProxBinSize int, pivotAddr []byte) (depth int) { // total number of peers in iteration var size int - // true if iteration has all prox peers - var b bool - - // last po recorded in iteration - var lastPo int - + var maxDepth int f := func(v pot.Val, i int) bool { // po == 256 means that addr is the pivot address(self) if i == 256 { @@ -463,38 +458,25 @@ func depthForPot(p *pot.Pot, minProxBinSize int, pivotAddr []byte) (depth int) { // this means we have all nn-peers. // depth is by default set to the bin of the farthest nn-peer if size == minProxBinSize { - b = true - depth = i - return true - } - - // if there are empty bins between farthest nn and current node, - // the depth should recalculated to be - // the farthest of those empty bins - // - // 0 abac ccde - // 1 2a2a - // 2 589f <--- nearest non-nn - // ============ DEPTH 3 =========== - // 3 <--- don't count as empty bins - // 4 <--- don't count as empty bins - // 5 cbcb cdcd <---- furthest nn - // 6 a1a2 b3c4 - if b && i < depth { - depth = i + 1 - lastPo = i + maxDepth = i return false } - lastPo = i + return true } p.EachNeighbour(pivotAddr, pof, f) - // cover edge case where more than one farthest nn - // AND we only have nn-peers - if lastPo == depth { - depth = 0 - } + p.EachBin(pivotAddr, pof, 0, func(po int, _ int, _ func(func(pot.Val, int) bool) bool) bool { + if po == depth { + if maxDepth == depth { + return false + } + depth++ + return true + } + return false + }) + return depth } diff --git a/swarm/network/kademlia_test.go b/swarm/network/kademlia_test.go index 184a2d9421..326070d9e2 100644 --- a/swarm/network/kademlia_test.go +++ b/swarm/network/kademlia_test.go @@ -89,61 +89,64 @@ func TestNeighbourhoodDepth(t *testing.T) { baseAddress := pot.NewAddressFromBytes(baseAddressBytes) - closerAddress := pot.RandomAddressAt(baseAddress, 7) - closerPeer := newTestDiscoveryPeer(closerAddress, kad) - kad.On(closerPeer) + // generate the peers + var peers []*Peer + for i := 0; i < 7; i++ { + addr := pot.RandomAddressAt(baseAddress, i) + peers = append(peers, newTestDiscoveryPeer(addr, kad)) + } + var sevenPeers []*Peer + for i := 0; i < 2; i++ { + addr := pot.RandomAddressAt(baseAddress, 7) + sevenPeers = append(sevenPeers, newTestDiscoveryPeer(addr, kad)) + } + + // first try with empty kademlia depth := kad.NeighbourhoodDepth() if depth != 0 { t.Fatalf("expected depth 0, was %d", depth) } - sameAddress := pot.RandomAddressAt(baseAddress, 7) - samePeer := newTestDiscoveryPeer(sameAddress, kad) - kad.On(samePeer) + // add one peer on 7 + kad.On(sevenPeers[0]) depth = kad.NeighbourhoodDepth() if depth != 0 { t.Fatalf("expected depth 0, was %d", depth) } - midAddress := pot.RandomAddressAt(baseAddress, 4) - midPeer := newTestDiscoveryPeer(midAddress, kad) - kad.On(midPeer) - depth = kad.NeighbourhoodDepth() - if depth != 5 { - t.Fatalf("expected depth 5, was %d", depth) - } - - kad.Off(midPeer) + // add a second + kad.On(sevenPeers[1]) depth = kad.NeighbourhoodDepth() if depth != 0 { t.Fatalf("expected depth 0, was %d", depth) } - fartherAddress := pot.RandomAddressAt(baseAddress, 1) - fartherPeer := newTestDiscoveryPeer(fartherAddress, kad) - kad.On(fartherPeer) - depth = kad.NeighbourhoodDepth() - if depth != 2 { - t.Fatalf("expected depth 2, was %d", depth) + for i, p := range peers { + kad.On(p) + depth = kad.NeighbourhoodDepth() + if depth != i+1 { + t.Fatalf("expected depth %d, was %d", i+1, depth) + } } - midSameAddress := pot.RandomAddressAt(baseAddress, 4) - midSamePeer := newTestDiscoveryPeer(midSameAddress, kad) - kad.Off(closerPeer) - kad.On(midPeer) - kad.On(midSamePeer) + kad.Off(sevenPeers[1]) depth = kad.NeighbourhoodDepth() - if depth != 2 { - t.Fatalf("expected depth 2, was %d", depth) + if depth != 6 { + t.Fatalf("expected depth 6, was %d", depth) } - kad.Off(fartherPeer) - log.Trace(kad.string()) - time.Sleep(time.Millisecond) + kad.Off(peers[4]) depth = kad.NeighbourhoodDepth() - if depth != 0 { - t.Fatalf("expected depth 0, was %d", depth) + if depth != 4 { + t.Fatalf("expected depth 4, was %d", depth) } + + kad.Off(peers[3]) + depth = kad.NeighbourhoodDepth() + if depth != 3 { + t.Fatalf("expected depth 3, was %d", depth) + } + } func testSuggestPeer(k *Kademlia, expAddr string, expPo int, expWant bool) error {