@@ -177,7 +177,7 @@ func (k *Kademlia) SuggestPeer() (a *BzzAddr, o int, want bool) {
177
177
k .lock .Lock ()
178
178
defer k .lock .Unlock ()
179
179
minsize := k .MinBinSize
180
- depth := k . neighbourhoodDepth ( )
180
+ depth := depthForPot ( k . conns , k . MinProxBinSize , k . base )
181
181
// if there is a callable neighbour within the current proxBin, connect
182
182
// this makes sure nearest neighbour set is fully connected
183
183
var ppo int
@@ -308,7 +308,7 @@ func (k *Kademlia) sendNeighbourhoodDepthChange() {
308
308
// It provides signaling of neighbourhood depth change.
309
309
// This part of the code is sending new neighbourhood depth to nDepthC if that condition is met.
310
310
if k .nDepthC != nil {
311
- nDepth := k . neighbourhoodDepth ( )
311
+ nDepth := depthForPot ( k . conns , k . MinProxBinSize , k . base )
312
312
if nDepth != k .nDepth {
313
313
k .nDepth = nDepth
314
314
k .nDepthC <- nDepth
@@ -364,7 +364,7 @@ func (k *Kademlia) EachBin(base []byte, pof pot.Pof, o int, eachBinFunc func(con
364
364
365
365
var startPo int
366
366
var endPo int
367
- kadDepth := k . neighbourhoodDepth ( )
367
+ kadDepth := depthForPot ( k . conns , k . MinProxBinSize , k . base )
368
368
369
369
k .conns .EachBin (base , pof , o , func (po , size int , f func (func (val pot.Val , i int ) bool ) bool ) bool {
370
370
if startPo > 0 && endPo != k .MaxProxDisplay {
@@ -398,7 +398,7 @@ func (k *Kademlia) eachConn(base []byte, o int, f func(*Peer, int, bool) bool) {
398
398
if len (base ) == 0 {
399
399
base = k .base
400
400
}
401
- depth := k . neighbourhoodDepth ( )
401
+ depth := depthForPot ( k . conns , k . MinProxBinSize , k . base )
402
402
k .conns .EachNeighbour (base , pof , func (val pot.Val , po int ) bool {
403
403
if po > o {
404
404
return true
@@ -420,7 +420,7 @@ func (k *Kademlia) eachAddr(base []byte, o int, f func(*BzzAddr, int, bool) bool
420
420
if len (base ) == 0 {
421
421
base = k .base
422
422
}
423
- depth := k . neighbourhoodDepth ( )
423
+ depth := depthForPot ( k . conns , k . MinProxBinSize , k . base )
424
424
k .addrs .EachNeighbour (base , pof , func (val pot.Val , po int ) bool {
425
425
if po > o {
426
426
return true
@@ -429,26 +429,72 @@ func (k *Kademlia) eachAddr(base []byte, o int, f func(*BzzAddr, int, bool) bool
429
429
})
430
430
}
431
431
432
- // neighbourhoodDepth returns the proximity order that defines the distance of
433
- // the nearest neighbour set with cardinality >= MinProxBinSize
434
- // if there is altogether less than MinProxBinSize peers it returns 0
435
432
func (k * Kademlia ) NeighbourhoodDepth () (depth int ) {
436
433
k .lock .RLock ()
437
434
defer k .lock .RUnlock ()
438
- return k . neighbourhoodDepth ( )
435
+ return depthForPot ( k . conns , k . MinProxBinSize , k . base )
439
436
}
440
437
441
- func (k * Kademlia ) neighbourhoodDepth () (depth int ) {
442
- if k .conns .Size () < k .MinProxBinSize {
438
+ // depthForPot returns the proximity order that defines the distance of
439
+ // the nearest neighbour set with cardinality >= MinProxBinSize
440
+ // if there is altogether less than MinProxBinSize peers it returns 0
441
+ // caller must hold the lock
442
+ func depthForPot (p * pot.Pot , minProxBinSize int , pivotAddr []byte ) (depth int ) {
443
+ if p .Size () <= minProxBinSize {
443
444
return 0
444
445
}
446
+
447
+ // total number of peers in iteration
445
448
var size int
449
+
450
+ // true if iteration has all prox peers
451
+ var b bool
452
+
453
+ // last po recorded in iteration
454
+ var lastPo int
455
+
446
456
f := func (v pot.Val , i int ) bool {
457
+ // po == 256 means that addr is the pivot address(self)
458
+ if i == 256 {
459
+ return true
460
+ }
447
461
size ++
448
- depth = i
449
- return size < k .MinProxBinSize
462
+
463
+ // this means we have all nn-peers.
464
+ // depth is by default set to the bin of the farthest nn-peer
465
+ if size == minProxBinSize {
466
+ b = true
467
+ depth = i
468
+ return true
469
+ }
470
+
471
+ // if there are empty bins between farthest nn and current node,
472
+ // the depth should recalculated to be
473
+ // the farthest of those empty bins
474
+ //
475
+ // 0 abac ccde
476
+ // 1 2a2a
477
+ // 2 589f <--- nearest non-nn
478
+ // ============ DEPTH 3 ===========
479
+ // 3 <--- don't count as empty bins
480
+ // 4 <--- don't count as empty bins
481
+ // 5 cbcb cdcd <---- furthest nn
482
+ // 6 a1a2 b3c4
483
+ if b && i < depth {
484
+ depth = i + 1
485
+ lastPo = i
486
+ return false
487
+ }
488
+ lastPo = i
489
+ return true
490
+ }
491
+ p .EachNeighbour (pivotAddr , pof , f )
492
+
493
+ // cover edge case where more than one farthest nn
494
+ // AND we only have nn-peers
495
+ if lastPo == depth {
496
+ depth = 0
450
497
}
451
- k .conns .EachNeighbour (k .base , pof , f )
452
498
return depth
453
499
}
454
500
@@ -508,7 +554,7 @@ func (k *Kademlia) string() string {
508
554
liverows := make ([]string , k .MaxProxDisplay )
509
555
peersrows := make ([]string , k .MaxProxDisplay )
510
556
511
- depth := k . neighbourhoodDepth ( )
557
+ depth := depthForPot ( k . conns , k . MinProxBinSize , k . base )
512
558
rest := k .conns .Size ()
513
559
k .conns .EachBin (k .base , pof , 0 , func (po , size int , f func (func (val pot.Val , i int ) bool ) bool ) bool {
514
560
var rowlen int
@@ -578,6 +624,7 @@ type PeerPot struct {
578
624
// as hexadecimal representations of the address.
579
625
// used for testing only
580
626
func NewPeerPotMap (kadMinProxSize int , addrs [][]byte ) map [string ]* PeerPot {
627
+
581
628
// create a table of all nodes for health check
582
629
np := pot .NewPot (nil , 0 )
583
630
for _ , addr := range addrs {
@@ -586,34 +633,47 @@ func NewPeerPotMap(kadMinProxSize int, addrs [][]byte) map[string]*PeerPot {
586
633
ppmap := make (map [string ]* PeerPot )
587
634
588
635
for i , a := range addrs {
589
- pl := 256
590
- prev := 256
636
+
637
+ // actual kademlia depth
638
+ depth := depthForPot (np , kadMinProxSize , a )
639
+
640
+ // upon entering a new iteration
641
+ // this will hold the value the po should be
642
+ // if it's one higher than the po in the last iteration
643
+ prevPo := 256
644
+
645
+ // all empty bins which are outside neighbourhood depth
591
646
var emptyBins []int
647
+
648
+ // all nn-peers
592
649
var nns [][]byte
593
- np .EachNeighbour (addrs [i ], pof , func (val pot.Val , po int ) bool {
594
- a := val .([]byte )
650
+
651
+ np .EachNeighbour (a , pof , func (val pot.Val , po int ) bool {
652
+ addr := val .([]byte )
653
+ // po == 256 means that addr is the pivot address(self)
595
654
if po == 256 {
596
655
return true
597
656
}
598
- if pl == 256 || pl == po {
599
- nns = append (nns , a )
600
- }
601
- if pl == 256 && len (nns ) >= kadMinProxSize {
602
- pl = po
603
- prev = po
657
+
658
+ // iterate through the neighbours, going from the closest to the farthest
659
+ // we calculate the nearest neighbours that should be in the set
660
+ // depth in this case equates to:
661
+ // 1. Within all bins that are higher or equal than depth there are
662
+ // at least minProxBinSize peers connected
663
+ // 2. depth-1 bin is not empty
664
+ if po >= depth {
665
+ nns = append (nns , addr )
666
+ prevPo = depth - 1
667
+ return true
604
668
}
605
- if prev < pl {
606
- for j := prev ; j > po ; j -- {
607
- emptyBins = append (emptyBins , j )
608
- }
669
+ for j := prevPo ; j > po ; j -- {
670
+ emptyBins = append (emptyBins , j )
609
671
}
610
- prev = po - 1
672
+ prevPo = po - 1
611
673
return true
612
674
})
613
- for j := prev ; j >= 0 ; j -- {
614
- emptyBins = append (emptyBins , j )
615
- }
616
- log .Trace (fmt .Sprintf ("%x NNS: %s" , addrs [i ][:4 ], LogAddrs (nns )))
675
+
676
+ log .Trace (fmt .Sprintf ("%x NNS: %s, emptyBins: %s" , addrs [i ][:4 ], LogAddrs (nns ), logEmptyBins (emptyBins )))
617
677
ppmap [common .Bytes2Hex (a )] = & PeerPot {nns , emptyBins }
618
678
}
619
679
return ppmap
@@ -628,7 +688,7 @@ func (k *Kademlia) saturation(n int) int {
628
688
prev ++
629
689
return prev == po && size >= n
630
690
})
631
- depth := k . neighbourhoodDepth ( )
691
+ depth := depthForPot ( k . conns , k . MinProxBinSize , k . base )
632
692
if depth < prev {
633
693
return depth
634
694
}
@@ -641,8 +701,11 @@ func (k *Kademlia) full(emptyBins []int) (full bool) {
641
701
prev := 0
642
702
e := len (emptyBins )
643
703
ok := true
644
- depth := k . neighbourhoodDepth ( )
704
+ depth := depthForPot ( k . conns , k . MinProxBinSize , k . base )
645
705
k .conns .EachBin (k .base , pof , 0 , func (po , _ int , _ func (func (val pot.Val , i int ) bool ) bool ) bool {
706
+ if po >= depth {
707
+ return false
708
+ }
646
709
if prev == depth + 1 {
647
710
return true
648
711
}
0 commit comments