Skip to content
This repository was archived by the owner on Aug 2, 2021. It is now read-only.

Commit afd1d9f

Browse files
nolashzelig
authored andcommitted
network: Add capability filtered depth calculation (#1787)
* network: Add capability filtered depth calculation * network: Typo in test fail error message
1 parent f37e979 commit afd1d9f

2 files changed

Lines changed: 74 additions & 0 deletions

File tree

network/kademlia.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ type capabilityIndex struct {
229229
*capability.Capability
230230
conns *pot.Pot
231231
addrs *pot.Pot
232+
depth int
232233
}
233234

234235
// NewCapabilityIndex creates a new capability index with a copy the provided capabilities array
@@ -455,6 +456,10 @@ func (k *Kademlia) setNeighbourhoodDepth() {
455456
k.nDepth = nDepth
456457
changed = true
457458
}
459+
// TODO: when hive is refactored, notifies should be made for depth change in any cap index
460+
for _, idx := range k.capabilityIndex {
461+
idx.depth = capabilityDepthForPot(idx, k.NeighbourhoodSize, k.base)
462+
}
458463
k.nDepthMu.Unlock()
459464

460465
if len(k.nDepthSig) > 0 && changed {
@@ -468,6 +473,7 @@ func (k *Kademlia) setNeighbourhoodDepth() {
468473
}
469474
}
470475
}
476+
471477
}
472478

473479
// NeighbourhoodDepth returns the value calculated by depthForPot function
@@ -478,6 +484,16 @@ func (k *Kademlia) NeighbourhoodDepth() int {
478484
return k.nDepth
479485
}
480486

487+
func (k *Kademlia) NeighbourhoodDepthCapability(s string) (int, error) {
488+
k.nDepthMu.RLock()
489+
defer k.nDepthMu.RUnlock()
490+
idx, ok := k.capabilityIndex[s]
491+
if !ok {
492+
return -1, fmt.Errorf("Unknown capability index %v", s)
493+
}
494+
return idx.depth, nil
495+
}
496+
481497
// SubscribeToNeighbourhoodDepthChange returns the channel that signals
482498
// when neighbourhood depth value is changed. The current neighbourhood depth
483499
// is returned by NeighbourhoodDepth method. Returned function unsubscribes
@@ -636,6 +652,10 @@ func neighbourhoodRadiusForPot(p *pot.Pot, neighbourhoodSize int, pivotAddr []by
636652
return depth
637653
}
638654

655+
func capabilityDepthForPot(idx *capabilityIndex, neighbourhoodSize int, pivotAddr []byte) (depth int) {
656+
return depthForPot(idx.conns, neighbourhoodSize, pivotAddr)
657+
}
658+
639659
// depthForPot returns the depth for the pot
640660
// depth is the radius of the minimal extension of nearest neighbourhood that
641661
// includes all empty PO bins. I.e., depth is the deepest PO such that

network/kademlia_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,3 +943,57 @@ func testCapabilityIndexRemove(t *testing.T) {
943943
t.Fatalf("EachAddrFiltered '42:101' expected 1 peer, got %d", c)
944944
}
945945
}
946+
947+
// TestCapabilityNeighbourhoodDepth tests that depth calculations filtered by capability is correct
948+
func TestCapabilityNeighbourhoodDepth(t *testing.T) {
949+
baseAddressBytes := RandomBzzAddr().OAddr
950+
kad := NewKademlia(baseAddressBytes, NewKadParams())
951+
cap_both := capability.NewCapability(42, 2)
952+
cap_both.Set(0)
953+
cap_both.Set(1)
954+
kad.RegisterCapabilityIndex("both", *cap_both)
955+
cap_one := capability.NewCapability(42, 2)
956+
cap_one.Set(0)
957+
kad.RegisterCapabilityIndex("one", *cap_one)
958+
959+
baseAddress := pot.NewAddressFromBytes(baseAddressBytes)
960+
961+
// generate the peers
962+
var peers []*Peer
963+
for i := 0; i < 2; i++ {
964+
addr := pot.RandomAddressAt(baseAddress, i)
965+
p := newTestDiscoveryPeer(addr, kad)
966+
p.BzzAddr.Capabilities.Add(cap_both)
967+
peers = append(peers)
968+
kad.Register(p.BzzAddr)
969+
kad.On(p)
970+
}
971+
972+
addrClosestBoth := pot.RandomAddressAt(baseAddress, 7)
973+
peerClosestBoth := newTestDiscoveryPeer(addrClosestBoth, kad)
974+
peerClosestBoth.BzzAddr.Capabilities.Add(cap_both)
975+
kad.Register(peerClosestBoth.BzzAddr)
976+
kad.On(peerClosestBoth)
977+
978+
addrClosestOne := pot.RandomAddressAt(baseAddress, 7)
979+
peerClosestOne := newTestDiscoveryPeer(addrClosestOne, kad)
980+
peerClosestOne.BzzAddr.Capabilities.Add(cap_one)
981+
kad.Register(peerClosestOne.BzzAddr)
982+
kad.On(peerClosestOne)
983+
984+
depth, err := kad.NeighbourhoodDepthCapability("both")
985+
if err != nil {
986+
t.Fatal(err)
987+
}
988+
if depth != 1 {
989+
t.Fatalf("cap 'both' expected depth 1, was %d", depth)
990+
}
991+
992+
depth, err = kad.NeighbourhoodDepthCapability("one")
993+
if err != nil {
994+
t.Fatal(err)
995+
}
996+
if depth != 2 {
997+
t.Fatalf("cap 'one' expected depth 2, was %d", depth)
998+
}
999+
}

0 commit comments

Comments
 (0)