swarm/network: Revised depth calculation with tests

This commit is contained in:
lash 2018-12-12 12:58:51 +01:00
parent e1edfe0689
commit 75495e5030
2 changed files with 50 additions and 65 deletions

View file

@ -447,12 +447,7 @@ func depthForPot(p *pot.Pot, minProxBinSize int, pivotAddr []byte) (depth int) {
// total number of peers in iteration // total number of peers in iteration
var size int var size int
// true if iteration has all prox peers var maxDepth int
var b bool
// last po recorded in iteration
var lastPo int
f := func(v pot.Val, i int) bool { f := func(v pot.Val, i int) bool {
// po == 256 means that addr is the pivot address(self) // po == 256 means that addr is the pivot address(self)
if i == 256 { 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. // this means we have all nn-peers.
// depth is by default set to the bin of the farthest nn-peer // depth is by default set to the bin of the farthest nn-peer
if size == minProxBinSize { if size == minProxBinSize {
b = true maxDepth = i
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
return false return false
} }
lastPo = i
return true return true
} }
p.EachNeighbour(pivotAddr, pof, f) p.EachNeighbour(pivotAddr, pof, f)
// cover edge case where more than one farthest nn p.EachBin(pivotAddr, pof, 0, func(po int, _ int, _ func(func(pot.Val, int) bool) bool) bool {
// AND we only have nn-peers if po == depth {
if lastPo == depth { if maxDepth == depth {
depth = 0 return false
} }
depth++
return true
}
return false
})
return depth return depth
} }

View file

@ -89,61 +89,64 @@ func TestNeighbourhoodDepth(t *testing.T) {
baseAddress := pot.NewAddressFromBytes(baseAddressBytes) baseAddress := pot.NewAddressFromBytes(baseAddressBytes)
closerAddress := pot.RandomAddressAt(baseAddress, 7) // generate the peers
closerPeer := newTestDiscoveryPeer(closerAddress, kad) var peers []*Peer
kad.On(closerPeer) 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() depth := kad.NeighbourhoodDepth()
if depth != 0 { if depth != 0 {
t.Fatalf("expected depth 0, was %d", depth) t.Fatalf("expected depth 0, was %d", depth)
} }
sameAddress := pot.RandomAddressAt(baseAddress, 7) // add one peer on 7
samePeer := newTestDiscoveryPeer(sameAddress, kad) kad.On(sevenPeers[0])
kad.On(samePeer)
depth = kad.NeighbourhoodDepth() depth = kad.NeighbourhoodDepth()
if depth != 0 { if depth != 0 {
t.Fatalf("expected depth 0, was %d", depth) t.Fatalf("expected depth 0, was %d", depth)
} }
midAddress := pot.RandomAddressAt(baseAddress, 4) // add a second
midPeer := newTestDiscoveryPeer(midAddress, kad) kad.On(sevenPeers[1])
kad.On(midPeer)
depth = kad.NeighbourhoodDepth()
if depth != 5 {
t.Fatalf("expected depth 5, was %d", depth)
}
kad.Off(midPeer)
depth = kad.NeighbourhoodDepth() depth = kad.NeighbourhoodDepth()
if depth != 0 { if depth != 0 {
t.Fatalf("expected depth 0, was %d", depth) t.Fatalf("expected depth 0, was %d", depth)
} }
fartherAddress := pot.RandomAddressAt(baseAddress, 1) for i, p := range peers {
fartherPeer := newTestDiscoveryPeer(fartherAddress, kad) kad.On(p)
kad.On(fartherPeer) depth = kad.NeighbourhoodDepth()
depth = kad.NeighbourhoodDepth() if depth != i+1 {
if depth != 2 { t.Fatalf("expected depth %d, was %d", i+1, depth)
t.Fatalf("expected depth 2, was %d", depth) }
} }
midSameAddress := pot.RandomAddressAt(baseAddress, 4) kad.Off(sevenPeers[1])
midSamePeer := newTestDiscoveryPeer(midSameAddress, kad)
kad.Off(closerPeer)
kad.On(midPeer)
kad.On(midSamePeer)
depth = kad.NeighbourhoodDepth() depth = kad.NeighbourhoodDepth()
if depth != 2 { if depth != 6 {
t.Fatalf("expected depth 2, was %d", depth) t.Fatalf("expected depth 6, was %d", depth)
} }
kad.Off(fartherPeer) kad.Off(peers[4])
log.Trace(kad.string())
time.Sleep(time.Millisecond)
depth = kad.NeighbourhoodDepth() depth = kad.NeighbourhoodDepth()
if depth != 0 { if depth != 4 {
t.Fatalf("expected depth 0, was %d", depth) 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 { func testSuggestPeer(k *Kademlia, expAddr string, expPo int, expWant bool) error {