2019-01-24 20:15:10 +00:00
|
|
|
// Copyright (C) 2019 Storj Labs, Inc.
|
2018-04-23 16:54:22 +01:00
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
2018-04-12 14:50:22 +01:00
|
|
|
package overlay
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2018-09-18 05:39:06 +01:00
|
|
|
|
2018-09-11 05:52:14 +01:00
|
|
|
"github.com/zeebo/errs"
|
2018-06-05 22:06:37 +01:00
|
|
|
"go.uber.org/zap"
|
2018-08-03 14:15:52 +01:00
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
"google.golang.org/grpc/status"
|
2018-12-20 13:57:54 +00:00
|
|
|
monkit "gopkg.in/spacemonkeygo/monkit.v2"
|
2018-06-22 14:33:57 +01:00
|
|
|
|
2018-09-18 05:39:06 +01:00
|
|
|
"storj.io/storj/pkg/pb"
|
2018-11-30 13:40:13 +00:00
|
|
|
"storj.io/storj/pkg/storj"
|
2018-06-22 14:33:57 +01:00
|
|
|
)
|
|
|
|
|
2018-09-11 05:52:14 +01:00
|
|
|
// ServerError creates class of errors for stack traces
|
|
|
|
var ServerError = errs.Class("Server Error")
|
|
|
|
|
2018-06-19 15:00:15 +01:00
|
|
|
// Server implements our overlay RPC service
|
|
|
|
type Server struct {
|
2019-01-29 19:42:43 +00:00
|
|
|
log *zap.Logger
|
|
|
|
cache *Cache
|
|
|
|
metrics *monkit.Registry
|
|
|
|
nodeSelectionConfig *NodeSelectionConfig
|
2018-06-05 22:06:37 +01:00
|
|
|
}
|
2018-04-12 14:50:22 +01:00
|
|
|
|
2018-11-19 20:39:25 +00:00
|
|
|
// NewServer creates a new Overlay Server
|
2019-01-29 19:42:43 +00:00
|
|
|
func NewServer(log *zap.Logger, cache *Cache, nodeSelectionConfig *NodeSelectionConfig) *Server {
|
2018-11-19 20:39:25 +00:00
|
|
|
return &Server{
|
2019-01-29 19:42:43 +00:00
|
|
|
cache: cache,
|
|
|
|
log: log,
|
|
|
|
metrics: monkit.Default,
|
|
|
|
nodeSelectionConfig: nodeSelectionConfig,
|
2018-11-19 20:39:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-18 13:54:08 +00:00
|
|
|
// Close closes resources
|
|
|
|
func (server *Server) Close() error { return nil }
|
|
|
|
|
2018-04-12 14:50:22 +01:00
|
|
|
// Lookup finds the address of a node in our overlay network
|
2019-01-23 19:58:44 +00:00
|
|
|
func (server *Server) Lookup(ctx context.Context, req *pb.LookupRequest) (_ *pb.LookupResponse, err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
2018-12-20 13:57:54 +00:00
|
|
|
na, err := server.cache.Get(ctx, req.NodeId)
|
2018-06-19 15:00:15 +01:00
|
|
|
|
2018-06-05 22:06:37 +01:00
|
|
|
if err != nil {
|
2018-12-20 13:57:54 +00:00
|
|
|
server.log.Error("Error looking up node", zap.Error(err), zap.String("nodeID", req.NodeId.String()))
|
2018-06-05 22:06:37 +01:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-09-18 05:39:06 +01:00
|
|
|
return &pb.LookupResponse{
|
2018-08-01 15:15:38 +01:00
|
|
|
Node: na,
|
2018-06-05 22:06:37 +01:00
|
|
|
}, nil
|
2018-04-12 14:50:22 +01:00
|
|
|
}
|
|
|
|
|
2018-11-20 16:54:52 +00:00
|
|
|
// BulkLookup finds the addresses of nodes in our overlay network
|
2019-01-23 19:58:44 +00:00
|
|
|
func (server *Server) BulkLookup(ctx context.Context, reqs *pb.LookupRequests) (_ *pb.LookupResponses, err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
2018-12-20 13:57:54 +00:00
|
|
|
ns, err := server.cache.GetAll(ctx, lookupRequestsToNodeIDs(reqs))
|
2018-09-11 05:52:14 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, ServerError.New("could not get nodes requested %s\n", err)
|
|
|
|
}
|
|
|
|
return nodesToLookupResponses(ns), nil
|
|
|
|
}
|
|
|
|
|
2019-01-29 19:42:43 +00:00
|
|
|
// FilterNodesRequest are the requirements for nodes from the overlay cache
|
|
|
|
type FilterNodesRequest struct {
|
|
|
|
MinReputation *pb.NodeStats
|
|
|
|
MinNodes int64
|
|
|
|
Opts *pb.OverlayOptions
|
|
|
|
NewNodePercentage float64
|
|
|
|
NewNodeAuditThreshold int64
|
|
|
|
}
|
|
|
|
|
2018-04-12 14:50:22 +01:00
|
|
|
// FindStorageNodes searches the overlay network for nodes that meet the provided requirements
|
2018-12-20 13:57:54 +00:00
|
|
|
func (server *Server) FindStorageNodes(ctx context.Context, req *pb.FindStorageNodesRequest) (resp *pb.FindStorageNodesResponse, err error) {
|
2019-01-23 19:58:44 +00:00
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
2019-01-29 19:42:43 +00:00
|
|
|
minStats := &pb.NodeStats{
|
|
|
|
AuditCount: server.nodeSelectionConfig.AuditCount,
|
|
|
|
AuditSuccessRatio: server.nodeSelectionConfig.AuditSuccessRatio,
|
|
|
|
UptimeCount: server.nodeSelectionConfig.UptimeCount,
|
|
|
|
UptimeRatio: server.nodeSelectionConfig.UptimeRatio,
|
2018-11-02 18:50:28 +00:00
|
|
|
}
|
|
|
|
|
2019-01-29 19:42:43 +00:00
|
|
|
filterNodesReq := &FilterNodesRequest{
|
|
|
|
MinReputation: minStats,
|
|
|
|
MinNodes: req.GetMinNodes(),
|
|
|
|
Opts: req.GetOpts(),
|
|
|
|
NewNodePercentage: server.nodeSelectionConfig.NewNodePercentage,
|
|
|
|
NewNodeAuditThreshold: server.nodeSelectionConfig.NewNodeAuditThreshold,
|
2018-08-01 15:15:38 +01:00
|
|
|
}
|
|
|
|
|
2019-01-29 19:42:43 +00:00
|
|
|
foundNodes, err := server.cache.db.FilterNodes(ctx, filterNodesReq)
|
2018-08-01 15:15:38 +01:00
|
|
|
if err != nil {
|
2019-01-29 19:42:43 +00:00
|
|
|
stat, _ := status.FromError(err)
|
|
|
|
if stat.Code() == codes.ResourceExhausted {
|
|
|
|
return &pb.FindStorageNodesResponse{
|
|
|
|
Nodes: foundNodes,
|
|
|
|
}, err
|
2018-08-01 15:15:38 +01:00
|
|
|
}
|
2019-01-29 19:42:43 +00:00
|
|
|
return nil, Error.Wrap(err)
|
2018-06-22 14:33:57 +01:00
|
|
|
}
|
|
|
|
|
2019-01-29 19:42:43 +00:00
|
|
|
return &pb.FindStorageNodesResponse{
|
|
|
|
Nodes: foundNodes,
|
|
|
|
}, nil
|
2018-10-15 18:42:36 +01:00
|
|
|
}
|
|
|
|
|
2018-11-29 18:39:27 +00:00
|
|
|
// lookupRequestsToNodeIDs returns the nodeIDs from the LookupRequests
|
|
|
|
func lookupRequestsToNodeIDs(reqs *pb.LookupRequests) (ids storj.NodeIDList) {
|
2018-11-24 02:46:53 +00:00
|
|
|
for _, v := range reqs.LookupRequest {
|
2018-11-29 18:39:27 +00:00
|
|
|
ids = append(ids, v.NodeId)
|
2018-09-11 05:52:14 +01:00
|
|
|
}
|
|
|
|
return ids
|
|
|
|
}
|
|
|
|
|
2018-10-09 17:09:33 +01:00
|
|
|
// nodesToLookupResponses returns LookupResponses from the nodes
|
2018-09-18 05:39:06 +01:00
|
|
|
func nodesToLookupResponses(nodes []*pb.Node) *pb.LookupResponses {
|
|
|
|
var rs []*pb.LookupResponse
|
2018-09-11 05:52:14 +01:00
|
|
|
for _, v := range nodes {
|
2018-09-18 05:39:06 +01:00
|
|
|
r := &pb.LookupResponse{Node: v}
|
2018-09-11 05:52:14 +01:00
|
|
|
rs = append(rs, r)
|
|
|
|
}
|
2018-11-24 02:46:53 +00:00
|
|
|
return &pb.LookupResponses{LookupResponse: rs}
|
2018-09-11 05:52:14 +01:00
|
|
|
}
|