github.com/ethersphere/bee/v2@v2.2.0/pkg/topology/kademlia/export_test.go (about) 1 // Copyright 2020 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package kademlia 6 7 import ( 8 "github.com/ethersphere/bee/v2/pkg/swarm" 9 "github.com/ethersphere/bee/v2/pkg/topology" 10 "github.com/ethersphere/bee/v2/pkg/topology/pslice" 11 ) 12 13 var ( 14 PruneOversaturatedBinsFunc = func(k *Kad) func(uint8) { 15 return k.pruneOversaturatedBins 16 } 17 GenerateCommonBinPrefixes = generateCommonBinPrefixes 18 ) 19 20 const ( 21 DefaultBitSuffixLength = defaultBitSuffixLength 22 DefaultSaturationPeers = defaultSaturationPeers 23 DefaultOverSaturationPeers = defaultOverSaturationPeers 24 ) 25 26 type PeerExcludeFunc = peerExcludeFunc 27 type ExcludeFunc = excludeFunc 28 29 func (k *Kad) IsWithinConnectionDepth(addr swarm.Address) bool { 30 return swarm.Proximity(k.base.Bytes(), addr.Bytes()) >= k.ConnectionDepth() 31 } 32 33 func (k *Kad) ConnectionDepth() uint8 { 34 k.depthMu.RLock() 35 defer k.depthMu.RUnlock() 36 return k.depth 37 } 38 39 func (k *Kad) StorageRadius() uint8 { 40 k.depthMu.RLock() 41 defer k.depthMu.RUnlock() 42 return k.storageRadius 43 } 44 45 // IsBalanced returns if Kademlia is balanced to bin. 46 func (k *Kad) IsBalanced(bin uint8) bool { 47 if int(bin) >= len(k.commonBinPrefixes) { 48 return false 49 } 50 51 // for each pseudo address 52 for i := range k.commonBinPrefixes[bin] { 53 pseudoAddr := k.commonBinPrefixes[bin][i] 54 closestConnectedPeer, err := closestPeer(k.connectedPeers, pseudoAddr) 55 if err != nil { 56 return false 57 } 58 59 closestConnectedPO := swarm.ExtendedProximity(closestConnectedPeer.Bytes(), pseudoAddr.Bytes()) 60 if int(closestConnectedPO) < int(bin)+k.opt.BitSuffixLength+1 { 61 return false 62 } 63 } 64 65 return true 66 } 67 68 func closestPeer(peers *pslice.PSlice, addr swarm.Address) (swarm.Address, error) { 69 closest := swarm.ZeroAddress 70 err := peers.EachBinRev(func(peer swarm.Address, po uint8) (bool, bool, error) { 71 if closest.IsZero() { 72 closest = peer 73 return false, false, nil 74 } 75 76 closer, err := peer.Closer(addr, closest) 77 if err != nil { 78 return false, false, err 79 } 80 if closer { 81 closest = peer 82 } 83 return false, false, nil 84 }) 85 if err != nil { 86 return closest, err 87 } 88 89 // check if found 90 if closest.IsZero() { 91 return closest, topology.ErrNotFound 92 } 93 94 return closest, nil 95 } 96 97 func (k *Kad) Trigger() { 98 k.manageC <- struct{}{} 99 }