c598ed034d
We realized that the Kademlia FindNear() function was 1. not using XOR distance (AKA _totally broken_) 2. largely a duplicate of the RoutingTable FindNear() function Changes in this PR: 1. upgraded RoutingTable FindNear() to use iterator and restrictions 2. removed unneeded RoutingTable interface 3. made Kademlia wrap methods that were previously accessed via RoutingTable 4. fixed the tests
137 lines
3.6 KiB
Go
137 lines
3.6 KiB
Go
// Copyright (C) 2019 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package kademlia_test
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/zeebo/errs"
|
|
"go.uber.org/zap/zaptest"
|
|
"golang.org/x/sync/errgroup"
|
|
|
|
"storj.io/storj/internal/testcontext"
|
|
"storj.io/storj/internal/testplanet"
|
|
"storj.io/storj/pkg/kademlia"
|
|
"storj.io/storj/pkg/pb"
|
|
"storj.io/storj/pkg/storj"
|
|
)
|
|
|
|
func TestDialer(t *testing.T) {
|
|
testplanet.Run(t, testplanet.Config{
|
|
SatelliteCount: 1, StorageNodeCount: 4, UplinkCount: 3,
|
|
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
|
expectedKademliaEntries := len(planet.Satellites) + len(planet.StorageNodes)
|
|
|
|
// TODO: also use satellites
|
|
peers := planet.StorageNodes
|
|
|
|
{ // Ping: storage node pings all other storage nodes
|
|
self := planet.StorageNodes[0]
|
|
|
|
dialer := kademlia.NewDialer(zaptest.NewLogger(t), self.Transport)
|
|
defer ctx.Check(dialer.Close)
|
|
|
|
var group errgroup.Group
|
|
|
|
for _, peer := range peers {
|
|
peer := peer
|
|
group.Go(func() error {
|
|
pinged, err := dialer.Ping(ctx, peer.Local())
|
|
var pingErr error
|
|
if !pinged {
|
|
pingErr = fmt.Errorf("ping to %s should have succeeded", peer.ID())
|
|
}
|
|
return errs.Combine(pingErr, err)
|
|
})
|
|
}
|
|
defer ctx.Check(group.Wait)
|
|
}
|
|
|
|
{ // Lookup: storage node query every node for everyone elese
|
|
self := planet.StorageNodes[1]
|
|
dialer := kademlia.NewDialer(zaptest.NewLogger(t), self.Transport)
|
|
defer ctx.Check(dialer.Close)
|
|
|
|
var group errgroup.Group
|
|
|
|
for _, peer := range peers {
|
|
peer := peer
|
|
group.Go(func() error {
|
|
for _, target := range peers {
|
|
errTag := fmt.Errorf("lookup peer:%s target:%s", peer.ID(), target.ID())
|
|
peer.Local().Type.DPanicOnInvalid("test client peer")
|
|
target.Local().Type.DPanicOnInvalid("test client target")
|
|
|
|
results, err := dialer.Lookup(ctx, self.Local(), peer.Local(), target.Local())
|
|
if err != nil {
|
|
return errs.Combine(errTag, err)
|
|
}
|
|
|
|
if containsResult(results, target.ID()) {
|
|
continue
|
|
}
|
|
|
|
// with small network we expect to return everything
|
|
if len(results) != expectedKademliaEntries {
|
|
return errs.Combine(errTag, fmt.Errorf("expected %d got %d: %s", expectedKademliaEntries, len(results), pb.NodesToIDs(results)))
|
|
}
|
|
|
|
return nil
|
|
}
|
|
return nil
|
|
})
|
|
}
|
|
|
|
defer ctx.Check(group.Wait)
|
|
}
|
|
|
|
{ // Lookup: storage node queries every node for missing storj.NodeID{} and storj.NodeID{255}
|
|
self := planet.StorageNodes[2]
|
|
dialer := kademlia.NewDialer(zaptest.NewLogger(t), self.Transport)
|
|
defer ctx.Check(dialer.Close)
|
|
|
|
targets := []storj.NodeID{
|
|
{}, // empty target
|
|
{255}, // non-empty
|
|
}
|
|
|
|
var group errgroup.Group
|
|
|
|
for _, target := range targets {
|
|
target := target
|
|
for _, peer := range peers {
|
|
peer := peer
|
|
group.Go(func() error {
|
|
errTag := fmt.Errorf("invalid lookup peer:%s target:%s", peer.ID(), target)
|
|
peer.Local().Type.DPanicOnInvalid("peer info")
|
|
results, err := dialer.Lookup(ctx, self.Local(), peer.Local(), pb.Node{Id: target, Type: pb.NodeType_STORAGE})
|
|
if err != nil {
|
|
return errs.Combine(errTag, err)
|
|
}
|
|
|
|
// with small network we expect to return everything
|
|
if len(results) != expectedKademliaEntries {
|
|
return errs.Combine(errTag, fmt.Errorf("expected %d got %d: %s", expectedKademliaEntries, len(results), pb.NodesToIDs(results)))
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
}
|
|
|
|
defer ctx.Check(group.Wait)
|
|
}
|
|
})
|
|
}
|
|
|
|
func containsResult(nodes []*pb.Node, target storj.NodeID) bool {
|
|
for _, node := range nodes {
|
|
if node.Id == target {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|