Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions pkg/topology/kademlia/kademlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -1356,22 +1356,16 @@ func (k *Kad) ClosestPeer(addr swarm.Address, includeSelf bool, filter topology.

closest := swarm.ZeroAddress

if includeSelf && k.reachability == p2p.ReachabilityStatusPublic {
if includeSelf {
closest = k.base
}

prox := swarm.Proximity(k.base.Bytes(), addr.Bytes())

// iterate starting from bin 0 to the maximum bin
err := k.EachConnectedPeerRev(func(peer swarm.Address, bin uint8) (bool, bool, error) {
if swarm.ContainsAddress(skipPeers, peer) {
return false, false, nil
}

if bin > prox && !closest.IsZero() {
return true, false, nil
}

if closest.IsZero() {
closest = peer
return false, false, nil
Expand Down
40 changes: 37 additions & 3 deletions pkg/topology/kademlia/kademlia_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,12 @@ func TestClosestPeer(t *testing.T) {
{
Address: swarm.MustParseHexAddress("6000000000000000000000000000000000000000000000000000000000000000"), // binary 0110 -> po 1 to base
},
{
Address: swarm.MustParseHexAddress("1000000000000000000000000000000000000000000000000000000000000000"), // binary 0001 -> po 3 to base
},
{
Address: swarm.MustParseHexAddress("0800000000000000000000000000000000000000000000000000000000000000"), // binary 0000 1 -> po 4 to base
},
}

disc := mock.NewDiscovery()
Expand Down Expand Up @@ -1002,7 +1008,7 @@ func TestClosestPeer(t *testing.T) {
addOne(t, beeCrypto.NewDefaultSigner(pk), kad, ab, v.Address)
}

waitPeers(t, kad, 3)
waitPeers(t, kad, 5)

// ClosestPeer only considers self when the node is publicly reachable.
kad.UpdateReachability(p2p.ReachabilityStatusPublic)
Expand All @@ -1011,8 +1017,10 @@ func TestClosestPeer(t *testing.T) {
chunkAddress swarm.Address // chunk address to test
expectedPeer int // points to the index of the connectedPeers slice. -1 means self (baseOverlay)
includeSelf bool
skipPeers []int // indexes of connectedPeers to skip
}{
{
// po(base, chunk) = 1, the peer in the deeper bin 3 must not stop the search
chunkAddress: swarm.MustParseHexAddress("7000000000000000000000000000000000000000000000000000000000000000"), // 0111, wants peer 2
expectedPeer: 2,
includeSelf: true,
Expand Down Expand Up @@ -1047,13 +1055,39 @@ func TestClosestPeer(t *testing.T) {
expectedPeer: -1,
includeSelf: true,
},
{
chunkAddress: swarm.MustParseHexAddress("0000001000000000000000000000000000000000000000000000000000000000"), // 1000 want peer 4
expectedPeer: 4,
includeSelf: false,
},
{
chunkAddress: swarm.MustParseHexAddress("0000001000000000000000000000000000000000000000000000000000000000"), // 1000 want peer 1
expectedPeer: 1, // smallest distance: 2894...
expectedPeer: 1, // smallest distance once peers 3 and 4 are skipped
includeSelf: false,
skipPeers: []int{3, 4},
},
{
// po(base, chunk) = 2, the peers in the deeper bins 3 and 4 are skipped
chunkAddress: swarm.MustParseHexAddress("3000000000000000000000000000000000000000000000000000000000000000"), // 0011, want peer 2
expectedPeer: 2,
includeSelf: false,
skipPeers: []int{3, 4},
},
{
// po(base, chunk) = 2, the peers in bins 0-1 are skipped, so only peers in bins
// deeper than po(base, chunk) are left. The peer in bin 4 is closer than the one
// in bin 3, so the search must not stop after the first deeper bin.
chunkAddress: swarm.MustParseHexAddress("2000000000000000000000000000000000000000000000000000000000000000"), // 0010, want peer 4
expectedPeer: 4,
includeSelf: false,
skipPeers: []int{0, 1, 2},
},
} {
peer, err := kad.ClosestPeer(tc.chunkAddress, tc.includeSelf, topology.Select{})
var skip []swarm.Address
for _, i := range tc.skipPeers {
skip = append(skip, connectedPeers[i].Address)
}
peer, err := kad.ClosestPeer(tc.chunkAddress, tc.includeSelf, topology.Select{}, skip...)
if tc.expectedPeer == -1 {
if !errors.Is(err, topology.ErrWantSelf) {
t.Fatalf("wanted %v but got %v", topology.ErrWantSelf, err)
Expand Down
Loading