Kademlia Inspector CLI (#657)

* initial commit of inspector gadget wireup

* change name of comman dline tool, setup grpc server

* Get inspector cli working with grpc client

* Wired up CountNodes command

* WIP getting buckets response working

* Added GetBucket command

* WIP working on get buckets command

* WIP working on bucket list

* Still WIP

* WIP getting bucket counts to work

* Some clean up of unnecessary changes

* List Buckets and Get Bucket are working

* Removing logs, getting ready for review

* initial commit of inspector gadget wireup

* change name of comman dline tool, setup grpc server

* Get inspector cli working with grpc client

* Wired up CountNodes command

* WIP getting buckets response working

* Added GetBucket command

* WIP working on get buckets command

* WIP working on bucket list

* Still WIP

* WIP getting bucket counts to work

* Some clean up of unnecessary changes

* List Buckets and Get Bucket are working

* Removing logs, getting ready for review

* Fix error return

* Trying to get tests passing

* Adds method on dht mock for tests

* Add dbx files back

* Fix package import error in dbx file

* Adds copyrights to pass linter

* tidy go mod

* Updates from code review

* Updates inspector to take flag arguments for address

* Format list-buckets output more prettier
This commit is contained in:
Dylan Lott 2018-11-21 10:31:27 -07:00 committed by GitHub
parent c829835dc1
commit 0d05cb26bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 884 additions and 311 deletions

View File

@ -16,6 +16,7 @@ import (
"storj.io/storj/pkg/cfgstruct"
"storj.io/storj/pkg/datarepair/checker"
"storj.io/storj/pkg/datarepair/repairer"
"storj.io/storj/pkg/inspector"
"storj.io/storj/pkg/kademlia"
"storj.io/storj/pkg/miniogw"
"storj.io/storj/pkg/overlay"
@ -38,6 +39,7 @@ type Satellite struct {
Kademlia kademlia.Config
PointerDB pointerdb.Config
Overlay overlay.Config
Inspector inspector.Config
Checker checker.Config
Repairer repairer.Config
Audit audit.Config
@ -111,6 +113,10 @@ func cmdRun(cmd *cobra.Command, args []string) (err error) {
runCfg.Satellite.Repairer,
runCfg.Satellite.BwAgreement,
runCfg.Satellite.Web,
// NB(dylan): Inspector is only used for local development and testing.
// It should not be added to the Satellite startup
runCfg.Satellite.Inspector,
)
}()

153
cmd/inspector/main.go Normal file
View File

@ -0,0 +1,153 @@
// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package main
import (
"context"
"flag"
"fmt"
"github.com/spf13/cobra"
"github.com/zeebo/errs"
"storj.io/storj/pkg/node"
"storj.io/storj/pkg/pb"
"storj.io/storj/pkg/process"
"storj.io/storj/pkg/provider"
"storj.io/storj/pkg/transport"
)
var (
// Addr is the address of Capt Planet from command flags
Addr = flag.String("address", "[::1]:7778", "address of captplanet to inspect")
// ErrInspectorDial throws when there are errors dialing the inspector server
ErrInspectorDial = errs.Class("error dialing inspector server:")
// ErrRequest is for gRPC request errors after dialing
ErrRequest = errs.Class("error processing request:")
// ErrIdentity is for errors during identity creation for this CLI
ErrIdentity = errs.Class("error creating identity:")
// Commander CLI
rootCmd = &cobra.Command{
Use: "inspector",
Short: "CLI for interacting with Storj Kademlia network",
}
countNodeCmd = &cobra.Command{
Use: "count",
Short: "count nodes in kademlia and overlay",
RunE: CountNodes,
}
getBucketsCmd = &cobra.Command{
Use: "list-buckets",
Short: "get all buckets in overlay",
RunE: GetBuckets,
}
getBucketCmd = &cobra.Command{
Use: "ls <bucket_id>",
Short: "get all nodes in bucket",
RunE: GetBucket,
}
)
// Inspector gives access to kademlia and overlay cache
type Inspector struct {
identity *provider.FullIdentity
client pb.InspectorClient
}
// NewInspector creates a new gRPC inspector server for access to kad
// and the overlay cache
func NewInspector(address string) (*Inspector, error) {
ctx := context.Background()
identity, err := node.NewFullIdentity(ctx, 12, 4)
if err != nil {
return &Inspector{}, ErrIdentity.Wrap(err)
}
tc := transport.NewClient(identity)
conn, err := tc.DialAddress(ctx, address)
if err != nil {
return &Inspector{}, ErrInspectorDial.Wrap(err)
}
c := pb.NewInspectorClient(conn)
return &Inspector{
identity: identity,
client: c,
}, nil
}
// CountNodes returns the number of nodes in the cache and kademlia
func CountNodes(cmd *cobra.Command, args []string) (err error) {
i, err := NewInspector(*Addr)
if err != nil {
return ErrInspectorDial.Wrap(err)
}
count, err := i.client.CountNodes(context.Background(), &pb.CountNodesRequest{})
if err != nil {
return ErrRequest.Wrap(err)
}
fmt.Printf("---------- \n - Kademlia: %+v\n - Overlay: %+v\n", count.Kademlia, count.Overlay)
return nil
}
// GetBuckets returns all buckets in the overlay cache's routing table
func GetBuckets(cmd *cobra.Command, args []string) (err error) {
i, err := NewInspector(*Addr)
if err != nil {
return ErrInspectorDial.Wrap(err)
}
buckets, err := i.client.GetBuckets(context.Background(), &pb.GetBucketsRequest{})
if err != nil {
return ErrRequest.Wrap(err)
}
fmt.Printf("Buckets ---------------- \n Total Buckets: %+v\n", buckets.Total)
for index, b := range buckets.Ids {
fmt.Printf("%+v %+v\n", index, b)
}
return nil
}
// GetBucket returns a bucket with given `id`
func GetBucket(cmd *cobra.Command, args []string) (err error) {
if len(args) < 1 {
return errs.New("Must provide at least one bucket ID")
}
i, err := NewInspector(*Addr)
if err != nil {
return ErrInspectorDial.Wrap(err)
}
bucket, err := i.client.GetBucket(context.Background(), &pb.GetBucketRequest{
Id: args[0],
})
if err != nil {
return ErrRequest.Wrap(err)
}
fmt.Printf("Bucket ----------- \n %+v\n", bucket)
return nil
}
func init() {
rootCmd.AddCommand(countNodeCmd)
rootCmd.AddCommand(getBucketsCmd)
rootCmd.AddCommand(getBucketCmd)
flag.Parse()
}
func main() {
process.Exec(rootCmd)
}

View File

@ -1,95 +0,0 @@
// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package main
import (
"context"
"fmt"
"github.com/spf13/cobra"
"storj.io/storj/pkg/node"
"storj.io/storj/pkg/overlay"
"storj.io/storj/pkg/process"
"storj.io/storj/pkg/provider"
)
var (
rootCmd = &cobra.Command{
Use: "inspector",
Short: "CLI for interacting with Storj Kademlia network",
}
getNodeCmd = &cobra.Command{
Use: "get",
Short: "get node with `id`",
RunE: GetNode,
}
listNodeCmd = &cobra.Command{
Use: "list-nodes",
Short: "get all nodes in cache",
RunE: ListNodes,
}
)
// Inspector gives access to kademlia and overlay cache
type Inspector struct {
overlay overlay.Client
identity *provider.FullIdentity
}
// NewInspector returns an Inspector client
func NewInspector(address string) (*Inspector, error) {
id, err := node.NewFullIdentity(context.Background(), 12, 4)
if err != nil {
return &Inspector{}, nil
}
overlay, err := overlay.NewOverlayClient(id, address)
if err != nil {
return &Inspector{}, nil
}
return &Inspector{
overlay: overlay,
identity: id,
}, nil
}
// GetNode returns a node with the requested ID or nothing at all
func GetNode(cmd *cobra.Command, args []string) (err error) {
i, err := NewInspector("127.0.0.1:7778")
if err != nil {
fmt.Printf("error dialing inspector: %+v\n", err)
return err
}
n := node.IDFromString("testnode")
found, err := i.overlay.Lookup(context.Background(), n)
if err != nil {
return err
}
fmt.Printf("### FOUND: %+v\n", found)
return nil
}
// ListNodes returns the nodes in the cache
func ListNodes(cmd *cobra.Command, args []string) (err error) {
i, err := NewInspector("127.0.0.1:7778")
if err != nil {
fmt.Printf("error dialing inspector: %+v\n", err)
return err
}
fmt.Printf("Inspector: %+v\n", i)
return nil
}
func init() {
rootCmd.AddCommand(getNodeCmd)
rootCmd.AddCommand(listNodeCmd)
}
func main() {
process.Exec(rootCmd)
}

View File

@ -8,6 +8,7 @@ import (
"time"
"storj.io/storj/pkg/pb"
"storj.io/storj/storage"
)
// NodeID is the unique identifier used for Nodes in the DHT
@ -34,8 +35,10 @@ type RoutingTable interface {
K() int
CacheSize() int
// Bucket methods
GetBucket(id string) (bucket Bucket, ok bool)
GetBuckets() ([]Bucket, error)
GetBucketIds() (storage.Keys, error)
FindNear(id NodeID, limit int) ([]*pb.Node, error)

View File

@ -13,6 +13,7 @@ import (
dht "storj.io/storj/pkg/dht"
pb "storj.io/storj/pkg/pb"
"storj.io/storj/storage"
)
// MockDHT is a mock of DHT interface
@ -237,6 +238,10 @@ func (m *MockRoutingTable) GetBuckets() ([]dht.Bucket, error) {
return ret0, ret1
}
func (m *MockRoutingTable) GetBucketIds() (storage.Keys, error) {
return nil, nil
}
// GetBuckets indicates an expected call of GetBuckets
func (mr *MockRoutingTableMockRecorder) GetBuckets() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetBuckets", reflect.TypeOf((*MockRoutingTable)(nil).GetBuckets))

54
pkg/inspector/config.go Normal file
View File

@ -0,0 +1,54 @@
// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package inspector
import (
"context"
"github.com/zeebo/errs"
"go.uber.org/zap"
monkit "gopkg.in/spacemonkeygo/monkit.v2"
"storj.io/storj/pkg/kademlia"
"storj.io/storj/pkg/overlay"
"storj.io/storj/pkg/pb"
"storj.io/storj/pkg/provider"
)
var (
mon = monkit.Package()
// Error is the main inspector error class for this package
Error = errs.Class("inspector server error:")
)
// Config is passed to CaptPlanet for bootup and configuration
type Config struct {
Enabled bool `help:"enable or disable the inspector" default:"true"`
}
// Run starts up the server and loads configs
func (c Config) Run(ctx context.Context, server *provider.Provider) (err error) {
defer mon.Task()(&ctx)(&err)
kad := kademlia.LoadFromContext(ctx)
if kad == nil {
return Error.New("programmer error: kademlia responsibility unstarted")
}
ol := overlay.LoadFromContext(ctx)
if ol == nil {
return Error.New("programmer error: overlay responsibility unstarted")
}
srv := &Server{
dht: kad,
cache: ol,
logger: zap.L(),
metrics: monkit.Default,
}
pb.RegisterInspectorServer(server.GRPC(), srv)
return server.Run(ctx)
}

71
pkg/inspector/server.go Normal file
View File

@ -0,0 +1,71 @@
// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package inspector
import (
"context"
"github.com/zeebo/errs"
"go.uber.org/zap"
monkit "gopkg.in/spacemonkeygo/monkit.v2"
"storj.io/storj/pkg/dht"
"storj.io/storj/pkg/overlay"
"storj.io/storj/pkg/pb"
)
var (
// ServerError is a gRPC server error for Inspector
ServerError = errs.Class("inspector server error:")
)
// Server holds references to cache and kad
type Server struct {
dht dht.DHT
cache *overlay.Cache
logger *zap.Logger
metrics *monkit.Registry
}
// CountNodes returns the number of nodes in the cache and in kademlia
func (srv *Server) CountNodes(ctx context.Context, req *pb.CountNodesRequest) (*pb.CountNodesResponse, error) {
return &pb.CountNodesResponse{
Kademlia: 0,
Overlay: 0,
}, nil
}
// GetBuckets returns all kademlia buckets for current kademlia instance
func (srv *Server) GetBuckets(ctx context.Context, req *pb.GetBucketsRequest) (*pb.GetBucketsResponse, error) {
rt, err := srv.dht.GetRoutingTable(ctx)
if err != nil {
return &pb.GetBucketsResponse{}, ServerError.Wrap(err)
}
b, err := rt.GetBucketIds()
if err != nil {
return nil, err
}
bytes := b.ByteSlices()
return &pb.GetBucketsResponse{
Total: int64(len(b)),
Ids: bytes,
}, nil
}
// GetBucket retrieves all of a given K buckets contents
func (srv *Server) GetBucket(ctx context.Context, req *pb.GetBucketRequest) (*pb.GetBucketResponse, error) {
rt, err := srv.dht.GetRoutingTable(ctx)
if err != nil {
return nil, err
}
bucket, ok := rt.GetBucket(req.Id)
if !ok {
return &pb.GetBucketResponse{}, ServerError.New("GetBuckets returned non-OK response")
}
return &pb.GetBucketResponse{
Id: req.Id,
Nodes: bucket.Nodes(),
}, nil
}

View File

@ -127,6 +127,15 @@ func (rt *RoutingTable) GetBuckets() (k []dht.Bucket, err error) {
return bs, nil
}
// GetBucketIds returns a storage.Keys type of bucket ID's in the Kademlia instance
func (rt *RoutingTable) GetBucketIds() (storage.Keys, error) {
kbuckets, err := rt.kadBucketDB.List(nil, 0)
if err != nil {
return nil, err
}
return kbuckets, nil
}
// FindNear returns the node corresponding to the provided nodeID
// returns all Nodes closest via XOR to the provided nodeID up to the provided limit
// always returns limit + self

View File

@ -20,6 +20,12 @@ const (
OverlayBucket = "overlay"
)
// ErrNodeNotFound error standardization
var ErrNodeNotFound = errs.New("Node not found")
// ErrBucketNotFound returns if a bucket is unable to be found in the routing table
var ErrBucketNotFound = errs.New("Bucket not found")
// OverlayError creates class of errors for stack traces
var OverlayError = errs.Class("Overlay Error")

View File

@ -8,4 +8,4 @@ import "storj.io/storj/pkg/storj"
// Path represents a object path
type Path = storj.Path
//go:generate protoc -I. --gogo_out=plugins=grpc:. meta.proto overlay.proto pointerdb.proto piecestore.proto bandwidth.proto kadcli.proto datarepair.proto
//go:generate protoc -I. --gogo_out=plugins=grpc:. meta.proto overlay.proto pointerdb.proto piecestore.proto bandwidth.proto inspector.proto datarepair.proto

520
pkg/pb/inspector.pb.go Normal file
View File

@ -0,0 +1,520 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: inspector.proto
package pb
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// CountNodes
type CountNodesResponse struct {
Kademlia int64 `protobuf:"varint,1,opt,name=kademlia,proto3" json:"kademlia,omitempty"`
Overlay int64 `protobuf:"varint,2,opt,name=overlay,proto3" json:"overlay,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CountNodesResponse) Reset() { *m = CountNodesResponse{} }
func (m *CountNodesResponse) String() string { return proto.CompactTextString(m) }
func (*CountNodesResponse) ProtoMessage() {}
func (*CountNodesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_inspector_4eafe550bfab534a, []int{0}
}
func (m *CountNodesResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CountNodesResponse.Unmarshal(m, b)
}
func (m *CountNodesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CountNodesResponse.Marshal(b, m, deterministic)
}
func (dst *CountNodesResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_CountNodesResponse.Merge(dst, src)
}
func (m *CountNodesResponse) XXX_Size() int {
return xxx_messageInfo_CountNodesResponse.Size(m)
}
func (m *CountNodesResponse) XXX_DiscardUnknown() {
xxx_messageInfo_CountNodesResponse.DiscardUnknown(m)
}
var xxx_messageInfo_CountNodesResponse proto.InternalMessageInfo
func (m *CountNodesResponse) GetKademlia() int64 {
if m != nil {
return m.Kademlia
}
return 0
}
func (m *CountNodesResponse) GetOverlay() int64 {
if m != nil {
return m.Overlay
}
return 0
}
type CountNodesRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CountNodesRequest) Reset() { *m = CountNodesRequest{} }
func (m *CountNodesRequest) String() string { return proto.CompactTextString(m) }
func (*CountNodesRequest) ProtoMessage() {}
func (*CountNodesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_inspector_4eafe550bfab534a, []int{1}
}
func (m *CountNodesRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CountNodesRequest.Unmarshal(m, b)
}
func (m *CountNodesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CountNodesRequest.Marshal(b, m, deterministic)
}
func (dst *CountNodesRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_CountNodesRequest.Merge(dst, src)
}
func (m *CountNodesRequest) XXX_Size() int {
return xxx_messageInfo_CountNodesRequest.Size(m)
}
func (m *CountNodesRequest) XXX_DiscardUnknown() {
xxx_messageInfo_CountNodesRequest.DiscardUnknown(m)
}
var xxx_messageInfo_CountNodesRequest proto.InternalMessageInfo
// GetBuckets
type GetBucketsRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetBucketsRequest) Reset() { *m = GetBucketsRequest{} }
func (m *GetBucketsRequest) String() string { return proto.CompactTextString(m) }
func (*GetBucketsRequest) ProtoMessage() {}
func (*GetBucketsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_inspector_4eafe550bfab534a, []int{2}
}
func (m *GetBucketsRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetBucketsRequest.Unmarshal(m, b)
}
func (m *GetBucketsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetBucketsRequest.Marshal(b, m, deterministic)
}
func (dst *GetBucketsRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetBucketsRequest.Merge(dst, src)
}
func (m *GetBucketsRequest) XXX_Size() int {
return xxx_messageInfo_GetBucketsRequest.Size(m)
}
func (m *GetBucketsRequest) XXX_DiscardUnknown() {
xxx_messageInfo_GetBucketsRequest.DiscardUnknown(m)
}
var xxx_messageInfo_GetBucketsRequest proto.InternalMessageInfo
type GetBucketsResponse struct {
Total int64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"`
Ids [][]byte `protobuf:"bytes,2,rep,name=ids,proto3" json:"ids,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetBucketsResponse) Reset() { *m = GetBucketsResponse{} }
func (m *GetBucketsResponse) String() string { return proto.CompactTextString(m) }
func (*GetBucketsResponse) ProtoMessage() {}
func (*GetBucketsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_inspector_4eafe550bfab534a, []int{3}
}
func (m *GetBucketsResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetBucketsResponse.Unmarshal(m, b)
}
func (m *GetBucketsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetBucketsResponse.Marshal(b, m, deterministic)
}
func (dst *GetBucketsResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetBucketsResponse.Merge(dst, src)
}
func (m *GetBucketsResponse) XXX_Size() int {
return xxx_messageInfo_GetBucketsResponse.Size(m)
}
func (m *GetBucketsResponse) XXX_DiscardUnknown() {
xxx_messageInfo_GetBucketsResponse.DiscardUnknown(m)
}
var xxx_messageInfo_GetBucketsResponse proto.InternalMessageInfo
func (m *GetBucketsResponse) GetTotal() int64 {
if m != nil {
return m.Total
}
return 0
}
func (m *GetBucketsResponse) GetIds() [][]byte {
if m != nil {
return m.Ids
}
return nil
}
// GetBucket
type GetBucketRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetBucketRequest) Reset() { *m = GetBucketRequest{} }
func (m *GetBucketRequest) String() string { return proto.CompactTextString(m) }
func (*GetBucketRequest) ProtoMessage() {}
func (*GetBucketRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_inspector_4eafe550bfab534a, []int{4}
}
func (m *GetBucketRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetBucketRequest.Unmarshal(m, b)
}
func (m *GetBucketRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetBucketRequest.Marshal(b, m, deterministic)
}
func (dst *GetBucketRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetBucketRequest.Merge(dst, src)
}
func (m *GetBucketRequest) XXX_Size() int {
return xxx_messageInfo_GetBucketRequest.Size(m)
}
func (m *GetBucketRequest) XXX_DiscardUnknown() {
xxx_messageInfo_GetBucketRequest.DiscardUnknown(m)
}
var xxx_messageInfo_GetBucketRequest proto.InternalMessageInfo
func (m *GetBucketRequest) GetId() string {
if m != nil {
return m.Id
}
return ""
}
type GetBucketResponse struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Nodes []*Node `protobuf:"bytes,2,rep,name=nodes,proto3" json:"nodes,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetBucketResponse) Reset() { *m = GetBucketResponse{} }
func (m *GetBucketResponse) String() string { return proto.CompactTextString(m) }
func (*GetBucketResponse) ProtoMessage() {}
func (*GetBucketResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_inspector_4eafe550bfab534a, []int{5}
}
func (m *GetBucketResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetBucketResponse.Unmarshal(m, b)
}
func (m *GetBucketResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetBucketResponse.Marshal(b, m, deterministic)
}
func (dst *GetBucketResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetBucketResponse.Merge(dst, src)
}
func (m *GetBucketResponse) XXX_Size() int {
return xxx_messageInfo_GetBucketResponse.Size(m)
}
func (m *GetBucketResponse) XXX_DiscardUnknown() {
xxx_messageInfo_GetBucketResponse.DiscardUnknown(m)
}
var xxx_messageInfo_GetBucketResponse proto.InternalMessageInfo
func (m *GetBucketResponse) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *GetBucketResponse) GetNodes() []*Node {
if m != nil {
return m.Nodes
}
return nil
}
type Bucket struct {
Nodes []*Node `protobuf:"bytes,2,rep,name=nodes,proto3" json:"nodes,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Bucket) Reset() { *m = Bucket{} }
func (m *Bucket) String() string { return proto.CompactTextString(m) }
func (*Bucket) ProtoMessage() {}
func (*Bucket) Descriptor() ([]byte, []int) {
return fileDescriptor_inspector_4eafe550bfab534a, []int{6}
}
func (m *Bucket) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Bucket.Unmarshal(m, b)
}
func (m *Bucket) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Bucket.Marshal(b, m, deterministic)
}
func (dst *Bucket) XXX_Merge(src proto.Message) {
xxx_messageInfo_Bucket.Merge(dst, src)
}
func (m *Bucket) XXX_Size() int {
return xxx_messageInfo_Bucket.Size(m)
}
func (m *Bucket) XXX_DiscardUnknown() {
xxx_messageInfo_Bucket.DiscardUnknown(m)
}
var xxx_messageInfo_Bucket proto.InternalMessageInfo
func (m *Bucket) GetNodes() []*Node {
if m != nil {
return m.Nodes
}
return nil
}
type BucketList struct {
Nodes []*Node `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *BucketList) Reset() { *m = BucketList{} }
func (m *BucketList) String() string { return proto.CompactTextString(m) }
func (*BucketList) ProtoMessage() {}
func (*BucketList) Descriptor() ([]byte, []int) {
return fileDescriptor_inspector_4eafe550bfab534a, []int{7}
}
func (m *BucketList) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_BucketList.Unmarshal(m, b)
}
func (m *BucketList) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_BucketList.Marshal(b, m, deterministic)
}
func (dst *BucketList) XXX_Merge(src proto.Message) {
xxx_messageInfo_BucketList.Merge(dst, src)
}
func (m *BucketList) XXX_Size() int {
return xxx_messageInfo_BucketList.Size(m)
}
func (m *BucketList) XXX_DiscardUnknown() {
xxx_messageInfo_BucketList.DiscardUnknown(m)
}
var xxx_messageInfo_BucketList proto.InternalMessageInfo
func (m *BucketList) GetNodes() []*Node {
if m != nil {
return m.Nodes
}
return nil
}
func init() {
proto.RegisterType((*CountNodesResponse)(nil), "inspector.CountNodesResponse")
proto.RegisterType((*CountNodesRequest)(nil), "inspector.CountNodesRequest")
proto.RegisterType((*GetBucketsRequest)(nil), "inspector.GetBucketsRequest")
proto.RegisterType((*GetBucketsResponse)(nil), "inspector.GetBucketsResponse")
proto.RegisterType((*GetBucketRequest)(nil), "inspector.GetBucketRequest")
proto.RegisterType((*GetBucketResponse)(nil), "inspector.GetBucketResponse")
proto.RegisterType((*Bucket)(nil), "inspector.Bucket")
proto.RegisterType((*BucketList)(nil), "inspector.BucketList")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// InspectorClient is the client API for Inspector service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type InspectorClient interface {
// CountNodes returns the number of nodes in the cache and in the routing table
CountNodes(ctx context.Context, in *CountNodesRequest, opts ...grpc.CallOption) (*CountNodesResponse, error)
// GetBuckets returns the k buckets from a Kademlia instance
GetBuckets(ctx context.Context, in *GetBucketsRequest, opts ...grpc.CallOption) (*GetBucketsResponse, error)
// GetBucket returns the details of a single k bucket from the kademlia instance
GetBucket(ctx context.Context, in *GetBucketRequest, opts ...grpc.CallOption) (*GetBucketResponse, error)
}
type inspectorClient struct {
cc *grpc.ClientConn
}
func NewInspectorClient(cc *grpc.ClientConn) InspectorClient {
return &inspectorClient{cc}
}
func (c *inspectorClient) CountNodes(ctx context.Context, in *CountNodesRequest, opts ...grpc.CallOption) (*CountNodesResponse, error) {
out := new(CountNodesResponse)
err := c.cc.Invoke(ctx, "/inspector.Inspector/CountNodes", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *inspectorClient) GetBuckets(ctx context.Context, in *GetBucketsRequest, opts ...grpc.CallOption) (*GetBucketsResponse, error) {
out := new(GetBucketsResponse)
err := c.cc.Invoke(ctx, "/inspector.Inspector/GetBuckets", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *inspectorClient) GetBucket(ctx context.Context, in *GetBucketRequest, opts ...grpc.CallOption) (*GetBucketResponse, error) {
out := new(GetBucketResponse)
err := c.cc.Invoke(ctx, "/inspector.Inspector/GetBucket", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// InspectorServer is the server API for Inspector service.
type InspectorServer interface {
// CountNodes returns the number of nodes in the cache and in the routing table
CountNodes(context.Context, *CountNodesRequest) (*CountNodesResponse, error)
// GetBuckets returns the k buckets from a Kademlia instance
GetBuckets(context.Context, *GetBucketsRequest) (*GetBucketsResponse, error)
// GetBucket returns the details of a single k bucket from the kademlia instance
GetBucket(context.Context, *GetBucketRequest) (*GetBucketResponse, error)
}
func RegisterInspectorServer(s *grpc.Server, srv InspectorServer) {
s.RegisterService(&_Inspector_serviceDesc, srv)
}
func _Inspector_CountNodes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CountNodesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(InspectorServer).CountNodes(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/inspector.Inspector/CountNodes",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(InspectorServer).CountNodes(ctx, req.(*CountNodesRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Inspector_GetBuckets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetBucketsRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(InspectorServer).GetBuckets(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/inspector.Inspector/GetBuckets",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(InspectorServer).GetBuckets(ctx, req.(*GetBucketsRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Inspector_GetBucket_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetBucketRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(InspectorServer).GetBucket(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/inspector.Inspector/GetBucket",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(InspectorServer).GetBucket(ctx, req.(*GetBucketRequest))
}
return interceptor(ctx, in, info, handler)
}
var _Inspector_serviceDesc = grpc.ServiceDesc{
ServiceName: "inspector.Inspector",
HandlerType: (*InspectorServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "CountNodes",
Handler: _Inspector_CountNodes_Handler,
},
{
MethodName: "GetBuckets",
Handler: _Inspector_GetBuckets_Handler,
},
{
MethodName: "GetBucket",
Handler: _Inspector_GetBucket_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "inspector.proto",
}
func init() { proto.RegisterFile("inspector.proto", fileDescriptor_inspector_4eafe550bfab534a) }
var fileDescriptor_inspector_4eafe550bfab534a = []byte{
// 306 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0xc1, 0x4e, 0x83, 0x40,
0x10, 0x86, 0x03, 0xd8, 0x2a, 0xa3, 0xd5, 0x3a, 0x7a, 0x20, 0x58, 0x93, 0x66, 0xbd, 0xf4, 0x22,
0x89, 0xf5, 0xea, 0xa9, 0x26, 0x2a, 0xc6, 0x78, 0xe0, 0xe8, 0x8d, 0x96, 0x3d, 0x6c, 0x8a, 0x2c,
0xb2, 0x8b, 0x89, 0x8f, 0xec, 0x5b, 0x18, 0xd8, 0x65, 0xa1, 0x96, 0x26, 0xbd, 0x31, 0xff, 0x3f,
0xf3, 0x0d, 0x33, 0xb3, 0x70, 0xc6, 0x32, 0x91, 0xd3, 0x95, 0xe4, 0x45, 0x90, 0x17, 0x5c, 0x72,
0x74, 0x8d, 0xe0, 0x8f, 0xf8, 0x37, 0x2d, 0xd2, 0xf8, 0x47, 0x39, 0xe4, 0x15, 0xf0, 0x91, 0x97,
0x99, 0x7c, 0xe7, 0x09, 0x15, 0x11, 0x15, 0x39, 0xcf, 0x04, 0x45, 0x1f, 0x8e, 0xd6, 0x71, 0x42,
0x3f, 0x53, 0x16, 0x7b, 0xd6, 0xd4, 0x9a, 0x39, 0x91, 0x89, 0xd1, 0x83, 0x43, 0x8d, 0xf0, 0xec,
0xda, 0x6a, 0x42, 0x72, 0x01, 0xe7, 0x5d, 0xd6, 0x57, 0x49, 0x85, 0xac, 0xc4, 0x67, 0x2a, 0x17,
0xe5, 0x6a, 0x4d, 0xa5, 0x11, 0x1f, 0x00, 0xbb, 0xa2, 0xee, 0x7a, 0x09, 0x03, 0xc9, 0x65, 0x9c,
0xea, 0x96, 0x2a, 0xc0, 0x31, 0x38, 0x2c, 0x11, 0x9e, 0x3d, 0x75, 0x66, 0x27, 0x51, 0xf5, 0x49,
0x08, 0x8c, 0x4d, 0xb5, 0x26, 0xe2, 0x29, 0xd8, 0x2c, 0xa9, 0x0b, 0xdd, 0xc8, 0x66, 0x09, 0x79,
0xe9, 0xb4, 0x35, 0x0d, 0xfe, 0x25, 0xe1, 0x0d, 0x0c, 0xb2, 0xea, 0x5f, 0x6b, 0xf8, 0xf1, 0x7c,
0x14, 0x34, 0xbb, 0xa9, 0x26, 0x88, 0x94, 0x47, 0x6e, 0x61, 0xa8, 0x30, 0xfb, 0xa5, 0xdf, 0x01,
0xa8, 0xf4, 0x37, 0x26, 0x3a, 0x25, 0xd6, 0xee, 0x92, 0xf9, 0xaf, 0x05, 0x6e, 0xd8, 0x1c, 0x08,
0x43, 0x80, 0x76, 0x8b, 0x38, 0x09, 0xda, 0x5b, 0x6e, 0x2d, 0xd7, 0xbf, 0xde, 0xe1, 0xea, 0x79,
0x43, 0x80, 0x76, 0xcd, 0x1b, 0xa8, 0xad, 0x93, 0x6c, 0xa0, 0x7a, 0x6e, 0xf3, 0x04, 0xae, 0x51,
0xf1, 0xaa, 0x2f, 0xb7, 0x01, 0x4d, 0xfa, 0x4d, 0xc5, 0x59, 0x1c, 0x7c, 0xd8, 0xf9, 0x72, 0x39,
0xac, 0x1f, 0xdf, 0xfd, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0e, 0x49, 0x34, 0xe2, 0xa9, 0x02,
0x00, 0x00,
}

56
pkg/pb/inspector.proto Normal file
View File

@ -0,0 +1,56 @@
// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
syntax = "proto3";
option go_package = "pb";
import "overlay.proto";
package inspector;
service Inspector {
// CountNodes returns the number of nodes in the cache and in the routing table
rpc CountNodes(CountNodesRequest) returns (CountNodesResponse);
// GetBuckets returns the k buckets from a Kademlia instance
rpc GetBuckets(GetBucketsRequest) returns (GetBucketsResponse);
// GetBucket returns the details of a single k bucket from the kademlia instance
rpc GetBucket(GetBucketRequest) returns (GetBucketResponse);
}
// CountNodes
message CountNodesResponse {
int64 kademlia = 1;
int64 overlay = 2;
}
message CountNodesRequest {
}
// GetBuckets
message GetBucketsRequest {
}
message GetBucketsResponse {
int64 total = 1;
repeated bytes ids = 2;
}
// GetBucket
message GetBucketRequest {
string id = 1;
}
message GetBucketResponse {
string id = 1;
repeated overlay.Node nodes = 2;
}
message Bucket {
repeated overlay.Node nodes = 2;
}
message BucketList {
repeated overlay.Node nodes = 1;
}

View File

@ -1,195 +0,0 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: kadcli.proto
package pb
import proto "github.com/gogo/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type CountNodesResponse struct {
Kademlia int64 `protobuf:"varint,1,opt,name=kademlia,proto3" json:"kademlia,omitempty"`
Overlay int64 `protobuf:"varint,2,opt,name=overlay,proto3" json:"overlay,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CountNodesResponse) Reset() { *m = CountNodesResponse{} }
func (m *CountNodesResponse) String() string { return proto.CompactTextString(m) }
func (*CountNodesResponse) ProtoMessage() {}
func (*CountNodesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_kadcli_70f58752d8646e9c, []int{0}
}
func (m *CountNodesResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CountNodesResponse.Unmarshal(m, b)
}
func (m *CountNodesResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CountNodesResponse.Marshal(b, m, deterministic)
}
func (dst *CountNodesResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_CountNodesResponse.Merge(dst, src)
}
func (m *CountNodesResponse) XXX_Size() int {
return xxx_messageInfo_CountNodesResponse.Size(m)
}
func (m *CountNodesResponse) XXX_DiscardUnknown() {
xxx_messageInfo_CountNodesResponse.DiscardUnknown(m)
}
var xxx_messageInfo_CountNodesResponse proto.InternalMessageInfo
func (m *CountNodesResponse) GetKademlia() int64 {
if m != nil {
return m.Kademlia
}
return 0
}
func (m *CountNodesResponse) GetOverlay() int64 {
if m != nil {
return m.Overlay
}
return 0
}
type CountNodesRequest struct {
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CountNodesRequest) Reset() { *m = CountNodesRequest{} }
func (m *CountNodesRequest) String() string { return proto.CompactTextString(m) }
func (*CountNodesRequest) ProtoMessage() {}
func (*CountNodesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_kadcli_70f58752d8646e9c, []int{1}
}
func (m *CountNodesRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CountNodesRequest.Unmarshal(m, b)
}
func (m *CountNodesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CountNodesRequest.Marshal(b, m, deterministic)
}
func (dst *CountNodesRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_CountNodesRequest.Merge(dst, src)
}
func (m *CountNodesRequest) XXX_Size() int {
return xxx_messageInfo_CountNodesRequest.Size(m)
}
func (m *CountNodesRequest) XXX_DiscardUnknown() {
xxx_messageInfo_CountNodesRequest.DiscardUnknown(m)
}
var xxx_messageInfo_CountNodesRequest proto.InternalMessageInfo
func init() {
proto.RegisterType((*CountNodesResponse)(nil), "kadcli.CountNodesResponse")
proto.RegisterType((*CountNodesRequest)(nil), "kadcli.CountNodesRequest")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// KadCliClient is the client API for KadCli service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type KadCliClient interface {
// CountNodes returns the number of nodes in the cache and in the routing table
CountNodes(ctx context.Context, in *CountNodesRequest, opts ...grpc.CallOption) (*CountNodesResponse, error)
}
type kadCliClient struct {
cc *grpc.ClientConn
}
func NewKadCliClient(cc *grpc.ClientConn) KadCliClient {
return &kadCliClient{cc}
}
func (c *kadCliClient) CountNodes(ctx context.Context, in *CountNodesRequest, opts ...grpc.CallOption) (*CountNodesResponse, error) {
out := new(CountNodesResponse)
err := c.cc.Invoke(ctx, "/kadcli.KadCli/CountNodes", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// KadCliServer is the server API for KadCli service.
type KadCliServer interface {
// CountNodes returns the number of nodes in the cache and in the routing table
CountNodes(context.Context, *CountNodesRequest) (*CountNodesResponse, error)
}
func RegisterKadCliServer(s *grpc.Server, srv KadCliServer) {
s.RegisterService(&_KadCli_serviceDesc, srv)
}
func _KadCli_CountNodes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CountNodesRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(KadCliServer).CountNodes(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/kadcli.KadCli/CountNodes",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(KadCliServer).CountNodes(ctx, req.(*CountNodesRequest))
}
return interceptor(ctx, in, info, handler)
}
var _KadCli_serviceDesc = grpc.ServiceDesc{
ServiceName: "kadcli.KadCli",
HandlerType: (*KadCliServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "CountNodes",
Handler: _KadCli_CountNodes_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "kadcli.proto",
}
func init() { proto.RegisterFile("kadcli.proto", fileDescriptor_kadcli_70f58752d8646e9c) }
var fileDescriptor_kadcli_70f58752d8646e9c = []byte{
// 153 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xc9, 0x4e, 0x4c, 0x49,
0xce, 0xc9, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0xf0, 0x94, 0xbc, 0xb8, 0x84,
0x9c, 0xf3, 0x4b, 0xf3, 0x4a, 0xfc, 0xf2, 0x53, 0x52, 0x8b, 0x83, 0x52, 0x8b, 0x0b, 0xf2, 0xf3,
0x8a, 0x53, 0x85, 0xa4, 0xb8, 0x38, 0xb2, 0x13, 0x53, 0x52, 0x73, 0x73, 0x32, 0x13, 0x25, 0x18,
0x15, 0x18, 0x35, 0x98, 0x83, 0xe0, 0x7c, 0x21, 0x09, 0x2e, 0xf6, 0xfc, 0xb2, 0xd4, 0xa2, 0x9c,
0xc4, 0x4a, 0x09, 0x26, 0xb0, 0x14, 0x8c, 0xab, 0x24, 0xcc, 0x25, 0x88, 0x6c, 0x56, 0x61, 0x69,
0x6a, 0x71, 0x89, 0x91, 0x2f, 0x17, 0x9b, 0x77, 0x62, 0x8a, 0x73, 0x4e, 0xa6, 0x90, 0x33, 0x17,
0x17, 0x42, 0x5a, 0x48, 0x52, 0x0f, 0xea, 0x1e, 0x0c, 0x2d, 0x52, 0x52, 0xd8, 0xa4, 0x20, 0x2e,
0x73, 0x62, 0x89, 0x62, 0x2a, 0x48, 0x4a, 0x62, 0x03, 0x7b, 0xc2, 0x18, 0x10, 0x00, 0x00, 0xff,
0xff, 0x53, 0xe2, 0x81, 0xad, 0xd4, 0x00, 0x00, 0x00,
}

View File

@ -1,20 +0,0 @@
// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
syntax = "proto3";
option go_package = "pb";
package kadcli;
service KadCli {
// CountNodes returns the number of nodes in the cache and in the routing table
rpc CountNodes(CountNodesRequest) returns (CountNodesResponse);
}
message CountNodesResponse {
int64 kademlia = 1;
int64 overlay = 2;
}
message CountNodesRequest {
}