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  }