storagenode/console: remove kademlia (#2942)

this is a trivial operation for storagenode/console, as it doesn't
really need or use kademlia in the first place.

What:

Removes kademlia from storagenode/console

Why:

We are in the process of getting rid of kademlia, and this is one place where it's particularly easy.

Please describe the tests:

Existing tests exercise storagenode/console behavior; if they continue to work, everything here should be tested satisfactorily.
Please describe the performance impact:

None
This commit is contained in:
paul cannon 2019-09-11 15:41:43 -05:00 committed by Jennifer Li Johnson
parent 7718802f0c
commit c139ed8ea1
16 changed files with 215 additions and 185 deletions

View File

@ -160,7 +160,7 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revDB extensions.R
return nil, errs.Combine(err, peer.Close()) return nil, errs.Combine(err, peer.Close())
} }
peer.Kademlia.Endpoint = kademlia.NewEndpoint(peer.Log.Named("kademlia:endpoint"), peer.Kademlia.Service, peer.Kademlia.RoutingTable, nil) peer.Kademlia.Endpoint = kademlia.NewEndpoint(peer.Log.Named("kademlia:endpoint"), peer.Kademlia.Service, nil, peer.Kademlia.RoutingTable, nil)
pb.RegisterNodesServer(peer.Server.GRPC(), peer.Kademlia.Endpoint) pb.RegisterNodesServer(peer.Server.GRPC(), peer.Kademlia.Endpoint)
peer.Kademlia.Inspector = kademlia.NewInspector(peer.Kademlia.Service, peer.Identity) peer.Kademlia.Inspector = kademlia.NewInspector(peer.Kademlia.Service, peer.Identity)

View File

@ -100,9 +100,6 @@ func printDashboard(data *pb.DashboardResponse) error {
w := tabwriter.NewWriter(color.Output, 0, 0, 1, ' ', 0) w := tabwriter.NewWriter(color.Output, 0, 0, 1, ' ', 0)
fmt.Fprintf(w, "ID\t%s\n", color.YellowString(data.NodeId.String())) fmt.Fprintf(w, "ID\t%s\n", color.YellowString(data.NodeId.String()))
if data.LastQueried.After(data.LastPinged) {
data.LastPinged = data.LastQueried
}
switch { switch {
case data.LastPinged.IsZero(): case data.LastPinged.IsZero():
fmt.Fprintf(w, "Last Contact\t%s\n", color.RedString("OFFLINE")) fmt.Fprintf(w, "Last Contact\t%s\n", color.RedString("OFFLINE"))

View File

@ -6,10 +6,12 @@ package kademlia
import ( import (
"context" "context"
"sync/atomic" "sync/atomic"
"time"
"github.com/zeebo/errs" "github.com/zeebo/errs"
"go.uber.org/zap" "go.uber.org/zap"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/peer"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
"storj.io/storj/pkg/identity" "storj.io/storj/pkg/identity"
@ -25,20 +27,26 @@ type SatelliteIDVerifier interface {
VerifySatelliteID(ctx context.Context, id storj.NodeID) error VerifySatelliteID(ctx context.Context, id storj.NodeID) error
} }
type pingStatsSource interface {
WasPinged(when time.Time, byID storj.NodeID, byAddr string)
}
// Endpoint implements the kademlia Endpoints // Endpoint implements the kademlia Endpoints
type Endpoint struct { type Endpoint struct {
log *zap.Logger log *zap.Logger
service *Kademlia service *Kademlia
pingStats pingStatsSource
routingTable *RoutingTable routingTable *RoutingTable
trust SatelliteIDVerifier trust SatelliteIDVerifier
connected int32 connected int32
} }
// NewEndpoint returns a new kademlia endpoint // NewEndpoint returns a new kademlia endpoint
func NewEndpoint(log *zap.Logger, service *Kademlia, routingTable *RoutingTable, trust SatelliteIDVerifier) *Endpoint { func NewEndpoint(log *zap.Logger, service *Kademlia, pingStats pingStatsSource, routingTable *RoutingTable, trust SatelliteIDVerifier) *Endpoint {
return &Endpoint{ return &Endpoint{
log: log, log: log,
service: service, service: service,
pingStats: pingStats,
routingTable: routingTable, routingTable: routingTable,
trust: trust, trust: trust,
} }
@ -47,7 +55,6 @@ func NewEndpoint(log *zap.Logger, service *Kademlia, routingTable *RoutingTable,
// Query is a node to node communication query // Query is a node to node communication query
func (endpoint *Endpoint) Query(ctx context.Context, req *pb.QueryRequest) (_ *pb.QueryResponse, err error) { func (endpoint *Endpoint) Query(ctx context.Context, req *pb.QueryRequest) (_ *pb.QueryResponse, err error) {
defer mon.Task()(&ctx)(&err) defer mon.Task()(&ctx)(&err)
endpoint.service.Queried()
if req.GetPingback() { if req.GetPingback() {
endpoint.pingback(ctx, req.Sender) endpoint.pingback(ctx, req.Sender)
@ -95,7 +102,23 @@ func (endpoint *Endpoint) pingback(ctx context.Context, target *pb.Node) {
// Ping provides an easy way to verify a node is online and accepting requests // Ping provides an easy way to verify a node is online and accepting requests
func (endpoint *Endpoint) Ping(ctx context.Context, req *pb.PingRequest) (_ *pb.PingResponse, err error) { func (endpoint *Endpoint) Ping(ctx context.Context, req *pb.PingRequest) (_ *pb.PingResponse, err error) {
defer mon.Task()(&ctx)(&err) defer mon.Task()(&ctx)(&err)
endpoint.service.Pinged() // NOTE: this code is very similar to that in storagenode/contact.(*Endpoint).PingNode().
// That other will be used going forward, and this will soon be gutted and deprecated. The
// code similarity will only exist until the transition away from Kademlia is complete.
p, ok := peer.FromContext(ctx)
if !ok {
return nil, status.Error(codes.Internal, "unable to get grpc peer from context")
}
peerID, err := identity.PeerIdentityFromPeer(p)
if err != nil {
return nil, status.Error(codes.Unauthenticated, err.Error())
}
endpoint.log.Debug("pinged", zap.Stringer("by", peerID.ID), zap.Stringer("srcAddr", p.Addr))
if endpoint.pingStats != nil {
endpoint.pingStats.WasPinged(time.Now(), peerID.ID, p.Addr.String())
} else {
endpoint.log.Debug("not updating pingStats because nil")
}
return &pb.PingResponse{}, nil return &pb.PingResponse{}, nil
} }

View File

@ -6,13 +6,12 @@ package kademlia
import ( import (
"context" "context"
"math/rand" "math/rand"
"sync"
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/zeebo/errs" "github.com/zeebo/errs"
"go.uber.org/zap" "go.uber.org/zap"
monkit "gopkg.in/spacemonkeygo/monkit.v2" "gopkg.in/spacemonkeygo/monkit.v2"
"storj.io/storj/internal/sync2" "storj.io/storj/internal/sync2"
"storj.io/storj/pkg/identity" "storj.io/storj/pkg/identity"
@ -51,10 +50,6 @@ type Kademlia struct {
refreshThreshold int64 refreshThreshold int64
RefreshBuckets sync2.Cycle RefreshBuckets sync2.Cycle
mu sync.Mutex
lastPinged time.Time
lastQueried time.Time
} }
// NewService returns a newly configured Kademlia instance // NewService returns a newly configured Kademlia instance
@ -81,34 +76,6 @@ func (k *Kademlia) Close() error {
return dialerErr return dialerErr
} }
// LastPinged returns last time someone pinged this node.
func (k *Kademlia) LastPinged() time.Time {
k.mu.Lock()
defer k.mu.Unlock()
return k.lastPinged
}
// Pinged notifies the service it has been remotely pinged.
func (k *Kademlia) Pinged() {
k.mu.Lock()
defer k.mu.Unlock()
k.lastPinged = time.Now()
}
// LastQueried returns last time someone queried this node.
func (k *Kademlia) LastQueried() time.Time {
k.mu.Lock()
defer k.mu.Unlock()
return k.lastQueried
}
// Queried notifies the service it has been remotely queried
func (k *Kademlia) Queried() {
k.mu.Lock()
defer k.mu.Unlock()
k.lastQueried = time.Now()
}
// FindNear returns all nodes from a starting node up to a maximum limit // FindNear returns all nodes from a starting node up to a maximum limit
// stored in the local routing table. // stored in the local routing table.
func (k *Kademlia) FindNear(ctx context.Context, start storj.NodeID, limit int) (_ []*pb.Node, err error) { func (k *Kademlia) FindNear(ctx context.Context, start storj.NodeID, limit int) (_ []*pb.Node, err error) {

View File

@ -163,7 +163,7 @@ func testNode(ctx *testcontext.Context, name string, t *testing.T, bn []pb.Node)
k, err := newKademlia(logger, pb.NodeType_STORAGE, bn, lis.Addr().String(), pb.NodeOperator{}, fid, defaultAlpha) k, err := newKademlia(logger, pb.NodeType_STORAGE, bn, lis.Addr().String(), pb.NodeOperator{}, fid, defaultAlpha)
require.NoError(t, err) require.NoError(t, err)
s := NewEndpoint(logger, k, k.routingTable, nil) s := NewEndpoint(logger, k, nil, k.routingTable, nil)
// new ident opts // new ident opts
serverOptions, err := tlsopts.NewOptions(fid, tlsopts.Config{ serverOptions, err := tlsopts.NewOptions(fid, tlsopts.Config{

View File

@ -1112,6 +1112,8 @@ type DashboardResponse struct {
Uptime *duration.Duration `protobuf:"bytes,8,opt,name=uptime,proto3" json:"uptime,omitempty"` Uptime *duration.Duration `protobuf:"bytes,8,opt,name=uptime,proto3" json:"uptime,omitempty"`
LastPinged time.Time `protobuf:"bytes,9,opt,name=last_pinged,json=lastPinged,proto3,stdtime" json:"last_pinged"` LastPinged time.Time `protobuf:"bytes,9,opt,name=last_pinged,json=lastPinged,proto3,stdtime" json:"last_pinged"`
LastQueried time.Time `protobuf:"bytes,10,opt,name=last_queried,json=lastQueried,proto3,stdtime" json:"last_queried"` LastQueried time.Time `protobuf:"bytes,10,opt,name=last_queried,json=lastQueried,proto3,stdtime" json:"last_queried"`
LastPingFromId *NodeID `protobuf:"bytes,11,opt,name=last_ping_from_id,json=lastPingFromId,proto3,customtype=NodeID" json:"last_ping_from_id,omitempty"`
LastPingFromAddress string `protobuf:"bytes,12,opt,name=last_ping_from_address,json=lastPingFromAddress,proto3" json:"last_ping_from_address,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -1204,6 +1206,13 @@ func (m *DashboardResponse) GetLastQueried() time.Time {
return time.Time{} return time.Time{}
} }
func (m *DashboardResponse) GetLastPingFromAddress() string {
if m != nil {
return m.LastPingFromAddress
}
return ""
}
type SegmentHealthRequest struct { type SegmentHealthRequest struct {
Bucket []byte `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"` Bucket []byte `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"`
EncryptedPath []byte `protobuf:"bytes,2,opt,name=encrypted_path,json=encryptedPath,proto3" json:"encrypted_path,omitempty"` EncryptedPath []byte `protobuf:"bytes,2,opt,name=encrypted_path,json=encryptedPath,proto3" json:"encrypted_path,omitempty"`
@ -1515,113 +1524,115 @@ func init() {
func init() { proto.RegisterFile("inspector.proto", fileDescriptor_a07d9034b2dd9d26) } func init() { proto.RegisterFile("inspector.proto", fileDescriptor_a07d9034b2dd9d26) }
var fileDescriptor_a07d9034b2dd9d26 = []byte{ var fileDescriptor_a07d9034b2dd9d26 = []byte{
// 1682 bytes of a gzipped FileDescriptorProto // 1728 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0x49, 0x73, 0x1b, 0xc5, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0x4b, 0x73, 0x23, 0x49,
0x17, 0xf7, 0x68, 0xb3, 0xf4, 0x24, 0x6b, 0x69, 0x3b, 0x89, 0xfe, 0x4a, 0x62, 0xf9, 0x3f, 0x2c, 0x11, 0x76, 0xeb, 0x65, 0x29, 0x25, 0xeb, 0x51, 0xf6, 0xce, 0x0a, 0xed, 0x8c, 0x65, 0x9a, 0xc7,
0x71, 0x62, 0x90, 0x83, 0x12, 0x0e, 0x29, 0x8a, 0x83, 0x65, 0x67, 0x51, 0x25, 0x24, 0xce, 0x38, 0x78, 0xd7, 0x20, 0x2f, 0xda, 0xd9, 0xc3, 0x06, 0xc1, 0xc1, 0xb2, 0x77, 0x76, 0x14, 0x3b, 0xcc,
0x70, 0xa0, 0x52, 0x4c, 0xb5, 0x34, 0x6d, 0x69, 0xb0, 0x34, 0x3d, 0x99, 0x69, 0x85, 0xe8, 0x0b, 0x78, 0xda, 0x03, 0x07, 0x62, 0x82, 0x8e, 0x92, 0xaa, 0x2c, 0x35, 0x96, 0xba, 0x7a, 0xba, 0x4b,
0x50, 0x70, 0x22, 0x17, 0x0e, 0x9c, 0x29, 0xbe, 0x01, 0x27, 0xae, 0x5c, 0xf8, 0x0c, 0x1c, 0xc2, 0xc3, 0xe8, 0x0f, 0x10, 0x70, 0x82, 0x0b, 0x07, 0xce, 0x04, 0xff, 0x80, 0x13, 0x57, 0x2e, 0xfc,
0x0d, 0xee, 0xdc, 0xb8, 0x51, 0xbd, 0xcc, 0xa6, 0x05, 0x9b, 0x02, 0x6e, 0x9a, 0xf7, 0x7e, 0xef, 0x06, 0x0e, 0xc3, 0x0d, 0xee, 0xdc, 0x88, 0xe0, 0x40, 0xd4, 0xa3, 0xab, 0xbb, 0xf5, 0xc0, 0x26,
0xf5, 0xaf, 0x5f, 0x2f, 0xef, 0xd7, 0x82, 0x8a, 0xed, 0xf8, 0x2e, 0xe9, 0x33, 0xea, 0xb5, 0x5c, 0x80, 0x9b, 0x3a, 0xf3, 0xcb, 0xac, 0xaf, 0xb2, 0x1e, 0xf9, 0x95, 0xa0, 0xe1, 0xf9, 0x51, 0x40,
0x8f, 0x32, 0x8a, 0x0a, 0xa1, 0xa1, 0x01, 0x03, 0x3a, 0xa0, 0xd2, 0xdc, 0x00, 0x87, 0x5a, 0x44, 0xc7, 0x9c, 0x85, 0xbd, 0x20, 0x64, 0x9c, 0xa1, 0x8a, 0x31, 0x74, 0x60, 0xc2, 0x26, 0x4c, 0x99,
0xfd, 0xae, 0xb8, 0xd4, 0x76, 0x18, 0xf1, 0xac, 0x9e, 0x32, 0x6c, 0x0e, 0x28, 0x1d, 0x8c, 0xc8, 0x3b, 0xe0, 0x33, 0x42, 0xf5, 0xef, 0x46, 0xc0, 0x3c, 0x9f, 0xd3, 0x90, 0x8c, 0xb4, 0xe1, 0x70,
0xae, 0xf8, 0xea, 0x4d, 0x8e, 0x77, 0xad, 0x89, 0x87, 0x99, 0x4d, 0x1d, 0xe5, 0x6f, 0xce, 0xfa, 0xc2, 0xd8, 0x64, 0x46, 0x4f, 0xe5, 0xd7, 0x68, 0x71, 0x7d, 0x4a, 0x16, 0x21, 0xe6, 0x1e, 0xf3,
0x99, 0x3d, 0x26, 0x3e, 0xc3, 0x63, 0x57, 0x02, 0xf4, 0x13, 0xd8, 0x7c, 0x60, 0xfb, 0xac, 0xeb, 0xb5, 0xbf, 0xbb, 0xea, 0xe7, 0xde, 0x9c, 0x46, 0x1c, 0xcf, 0x03, 0x05, 0xb0, 0x6f, 0xe0, 0xf0,
0x79, 0xc4, 0xc5, 0x1e, 0xee, 0x8d, 0xc8, 0x11, 0x19, 0x8c, 0x89, 0xc3, 0x7c, 0x83, 0x3c, 0x9b, 0xa9, 0x17, 0xf1, 0x61, 0x18, 0xd2, 0x00, 0x87, 0x78, 0x34, 0xa3, 0x57, 0x74, 0x32, 0xa7, 0x3e,
0x10, 0x9f, 0xa1, 0x0d, 0xc8, 0x8e, 0xec, 0xb1, 0xcd, 0xea, 0xda, 0x96, 0xb6, 0x9d, 0x35, 0xe4, 0x8f, 0x1c, 0xfa, 0x7a, 0x41, 0x23, 0x8e, 0x0e, 0xa0, 0x38, 0xf3, 0xe6, 0x1e, 0x6f, 0x5b, 0x47,
0x07, 0xba, 0x01, 0xe7, 0x47, 0xd8, 0x67, 0xa6, 0x4f, 0x88, 0x63, 0xfa, 0x32, 0xc4, 0x74, 0x31, 0xd6, 0x71, 0xd1, 0x51, 0x1f, 0xe8, 0x13, 0xb8, 0x37, 0xc3, 0x11, 0x77, 0x23, 0x4a, 0x7d, 0x37,
0x1b, 0xd6, 0x53, 0x5b, 0xda, 0x76, 0xc9, 0x58, 0xe7, 0xde, 0x23, 0x42, 0x1c, 0x95, 0xee, 0x10, 0x52, 0x21, 0x6e, 0x80, 0xf9, 0xb4, 0x9d, 0x3b, 0xb2, 0x8e, 0x6b, 0xce, 0xbe, 0xf0, 0x5e, 0x51,
0xb3, 0xa1, 0xfe, 0xab, 0x06, 0x68, 0x7e, 0x24, 0x84, 0x20, 0x23, 0x22, 0x35, 0x11, 0x29, 0x7e, 0xea, 0xeb, 0x74, 0x97, 0x98, 0x4f, 0xed, 0xbf, 0x5a, 0x80, 0xd6, 0x47, 0x42, 0x08, 0x0a, 0x32,
0xa3, 0x5b, 0x50, 0x0e, 0xb2, 0x5a, 0x84, 0x61, 0x7b, 0x24, 0xf2, 0x16, 0xdb, 0xa8, 0x15, 0x95, 0xd2, 0x92, 0x91, 0xf2, 0x37, 0xfa, 0x0c, 0xea, 0x71, 0x56, 0x42, 0x39, 0xf6, 0x66, 0x32, 0x6f,
0xe0, 0x50, 0xfe, 0x32, 0xd6, 0x14, 0xf2, 0x40, 0x00, 0x51, 0x13, 0x8a, 0x23, 0xea, 0x33, 0xd3, 0xb5, 0x8f, 0x7a, 0x49, 0x09, 0x2e, 0xd5, 0x2f, 0x67, 0x4f, 0x23, 0x2f, 0x24, 0x10, 0x75, 0xa1,
0xb5, 0x49, 0x9f, 0xf8, 0xf5, 0xb4, 0xa0, 0x0d, 0xdc, 0x74, 0x28, 0x2c, 0xa8, 0x05, 0x82, 0x9d, 0x3a, 0x63, 0x11, 0x77, 0x03, 0x8f, 0x8e, 0x69, 0xd4, 0xce, 0x4b, 0xda, 0x20, 0x4c, 0x97, 0xd2,
0xc9, 0x89, 0xd8, 0x9e, 0x89, 0x19, 0x23, 0x63, 0x97, 0xd5, 0x33, 0x5b, 0xda, 0x76, 0xda, 0xa8, 0x82, 0x7a, 0x20, 0xd9, 0xb9, 0x82, 0x88, 0x17, 0xba, 0x98, 0x73, 0x3a, 0x0f, 0x78, 0xbb, 0x70,
0x71, 0x97, 0x21, 0x3c, 0x7b, 0xd2, 0x81, 0xae, 0xc3, 0x46, 0x12, 0x6a, 0xf6, 0xe9, 0xc4, 0x61, 0x64, 0x1d, 0xe7, 0x9d, 0x96, 0x70, 0x39, 0xd2, 0x73, 0xa6, 0x1c, 0xe8, 0x63, 0x38, 0xc8, 0x42,
0xf5, 0xac, 0x08, 0x40, 0x5e, 0x1c, 0xbc, 0xcf, 0x3d, 0xfa, 0x53, 0x68, 0x2e, 0xad, 0xaa, 0xef, 0xdd, 0x31, 0x5b, 0xf8, 0xbc, 0x5d, 0x94, 0x01, 0x28, 0x4c, 0x83, 0xcf, 0x85, 0xc7, 0x7e, 0x05,
0x52, 0xc7, 0x27, 0xe8, 0x16, 0xe4, 0x15, 0x6d, 0xbf, 0xae, 0x6d, 0xa5, 0xb7, 0x8b, 0xed, 0xcb, 0xdd, 0xad, 0x55, 0x8d, 0x02, 0xe6, 0x47, 0x14, 0x7d, 0x06, 0x65, 0x4d, 0x3b, 0x6a, 0x5b, 0x47,
0xad, 0x68, 0x47, 0xcc, 0x47, 0x1a, 0x21, 0x5c, 0xbf, 0x06, 0x48, 0x0c, 0xf3, 0x90, 0x5a, 0x24, 0xf9, 0xe3, 0x6a, 0xff, 0x41, 0x2f, 0xd9, 0x11, 0xeb, 0x91, 0x8e, 0x81, 0xdb, 0x1f, 0x01, 0x92,
0x4a, 0xb8, 0x01, 0x59, 0x49, 0x4b, 0x13, 0xb4, 0xe4, 0x87, 0xbe, 0x0e, 0xb5, 0x38, 0x56, 0x2c, 0xc3, 0x3c, 0x63, 0x84, 0x26, 0x09, 0x0f, 0xa0, 0xa8, 0x68, 0x59, 0x92, 0x96, 0xfa, 0xb0, 0xf7,
0xa9, 0x7e, 0x1e, 0x36, 0xee, 0x12, 0xd6, 0x99, 0xf4, 0x4f, 0x08, 0xe3, 0x3c, 0x03, 0xfb, 0xef, 0xa1, 0x95, 0xc6, 0xca, 0x25, 0xb5, 0xef, 0xc1, 0xc1, 0x17, 0x94, 0x0f, 0x16, 0xe3, 0x1b, 0xca,
0x1a, 0x9c, 0x9b, 0x71, 0xa8, 0xe4, 0x7b, 0xb0, 0xda, 0x13, 0xd6, 0x80, 0xec, 0x95, 0x18, 0xd9, 0x05, 0xcf, 0xd8, 0xfe, 0x77, 0x0b, 0xde, 0x5b, 0x71, 0xe8, 0xe4, 0x67, 0xb0, 0x3b, 0x92, 0xd6,
0x85, 0x21, 0x2d, 0x69, 0x32, 0x82, 0xb8, 0xc6, 0xd7, 0x1a, 0xe4, 0xa4, 0x0d, 0xed, 0x40, 0x41, 0x98, 0xec, 0xc3, 0x14, 0xd9, 0x8d, 0x21, 0x3d, 0x65, 0x72, 0xe2, 0xb8, 0xce, 0xaf, 0x2d, 0x28,
0x5a, 0x4d, 0xdb, 0x92, 0xab, 0xde, 0x29, 0xff, 0xf4, 0xaa, 0xb9, 0xf2, 0xf3, 0xab, 0x66, 0x8e, 0x29, 0x1b, 0x3a, 0x81, 0x8a, 0xb2, 0xba, 0x1e, 0x51, 0xab, 0x3e, 0xa8, 0xff, 0xe9, 0x5d, 0x77,
0x13, 0xed, 0x1e, 0x18, 0x79, 0x09, 0xe8, 0x5a, 0x68, 0x17, 0xd6, 0x3c, 0x3a, 0x61, 0xb6, 0x33, 0xe7, 0xcf, 0xef, 0xba, 0x25, 0x41, 0x74, 0x78, 0xe1, 0x94, 0x15, 0x60, 0x48, 0xd0, 0x29, 0xec,
0x30, 0xf9, 0x49, 0xf0, 0xeb, 0x29, 0x41, 0x00, 0x5a, 0xe2, 0x5c, 0x70, 0xb8, 0x51, 0x52, 0x00, 0x85, 0x6c, 0xc1, 0x3d, 0x7f, 0xe2, 0x8a, 0x93, 0x10, 0xb5, 0x73, 0x92, 0x00, 0xf4, 0xe4, 0xb9,
0x31, 0x49, 0xf4, 0x36, 0x94, 0xfa, 0xb8, 0x3f, 0x24, 0x96, 0xc2, 0xa7, 0xe7, 0xf0, 0x45, 0xe9, 0x10, 0x70, 0xa7, 0xa6, 0x01, 0x72, 0x92, 0xe8, 0xdb, 0x50, 0x1b, 0xe3, 0xf1, 0x94, 0x12, 0x8d,
0x17, 0x70, 0x5e, 0xa1, 0x70, 0x02, 0x61, 0x85, 0xee, 0x01, 0x8a, 0x1b, 0xa3, 0x12, 0x33, 0xca, 0xcf, 0xaf, 0xe1, 0xab, 0xca, 0x2f, 0xe1, 0xa2, 0x42, 0x66, 0x02, 0xa6, 0x42, 0x4f, 0x00, 0xa5,
0xf0, 0x28, 0x28, 0xb1, 0xf8, 0x40, 0x97, 0x20, 0x6d, 0x5b, 0x92, 0x56, 0xa9, 0x03, 0xb1, 0x39, 0x8d, 0x49, 0x89, 0x39, 0xe3, 0x78, 0x16, 0x97, 0x58, 0x7e, 0xa0, 0xfb, 0x90, 0xf7, 0x88, 0xa2,
0x70, 0xb3, 0xde, 0x86, 0x6a, 0x98, 0x29, 0x38, 0x52, 0x9b, 0x90, 0x5a, 0x3a, 0xf1, 0x94, 0x6d, 0x55, 0x1b, 0x40, 0x6a, 0x0e, 0xc2, 0x6c, 0xf7, 0xa1, 0x69, 0x32, 0xc5, 0x47, 0xea, 0x10, 0x72,
0xe9, 0x1f, 0xc6, 0x28, 0x85, 0x83, 0x9f, 0x12, 0x84, 0xb6, 0x20, 0xbb, 0xac, 0x3e, 0xd2, 0xa1, 0x5b, 0x27, 0x9e, 0xf3, 0x88, 0xfd, 0x83, 0x14, 0x25, 0x33, 0xf8, 0x2d, 0x41, 0xe8, 0x08, 0x8a,
0xb7, 0x00, 0xa2, 0x75, 0x8a, 0xf0, 0xda, 0x32, 0xfc, 0x7d, 0xa8, 0x1c, 0xaa, 0xaa, 0x9e, 0x91, 0xdb, 0xea, 0xa3, 0x1c, 0x76, 0x0f, 0x20, 0x59, 0xa7, 0x04, 0x6f, 0x6d, 0xc3, 0x7f, 0x09, 0x8d,
0x39, 0xaa, 0xc3, 0x2a, 0xb6, 0x2c, 0x8f, 0xf8, 0xbe, 0x38, 0xaf, 0x05, 0x23, 0xf8, 0xd4, 0x75, 0x4b, 0x5d, 0xd5, 0x3b, 0x32, 0x47, 0x6d, 0xd8, 0xc5, 0x84, 0x84, 0x34, 0x8a, 0xe4, 0x79, 0xad,
0xa8, 0x46, 0xc9, 0xd4, 0x94, 0xca, 0x90, 0xa2, 0x27, 0x22, 0x5b, 0xde, 0x48, 0xd1, 0x13, 0xfd, 0x38, 0xf1, 0xa7, 0x6d, 0x43, 0x33, 0x49, 0xa6, 0xa7, 0x54, 0x87, 0x1c, 0xbb, 0x91, 0xd9, 0xca,
0x7d, 0xa8, 0x3d, 0xa0, 0xf4, 0x64, 0xe2, 0xc6, 0x87, 0x2c, 0x87, 0x43, 0x16, 0x4e, 0x19, 0xe2, 0x4e, 0x8e, 0xdd, 0xd8, 0xdf, 0x83, 0xd6, 0x53, 0xc6, 0x6e, 0x16, 0x41, 0x7a, 0xc8, 0xba, 0x19,
0x29, 0xa0, 0x78, 0x78, 0x58, 0xb7, 0x0c, 0x9f, 0x8e, 0xc8, 0x90, 0x9c, 0xa6, 0xb0, 0xa3, 0x37, 0xb2, 0x72, 0xcb, 0x10, 0xaf, 0x00, 0xa5, 0xc3, 0x4d, 0xdd, 0x0a, 0x62, 0x3a, 0x32, 0x43, 0x76,
0x21, 0x33, 0x26, 0x0c, 0x87, 0xf7, 0x4b, 0xe8, 0xff, 0x80, 0x30, 0x6c, 0x61, 0x86, 0x0d, 0xe1, 0x9a, 0xd2, 0x8e, 0xbe, 0x09, 0x85, 0x39, 0xe5, 0xd8, 0xdc, 0x2f, 0xc6, 0xff, 0x7d, 0xca, 0x31,
0xd7, 0x3f, 0x81, 0x8a, 0x98, 0xa8, 0x73, 0x4c, 0xcf, 0x5a, 0x8d, 0x9d, 0x24, 0xd5, 0x62, 0xbb, 0xc1, 0x1c, 0x3b, 0xd2, 0x6f, 0xff, 0x18, 0x1a, 0x72, 0xa2, 0xfe, 0x35, 0xbb, 0x6b, 0x35, 0x4e,
0x16, 0x65, 0xdf, 0x93, 0x8e, 0x88, 0xfd, 0x8f, 0x1a, 0x54, 0xa3, 0x01, 0x14, 0x79, 0x1d, 0x32, 0xb2, 0x54, 0xab, 0xfd, 0x56, 0x92, 0xfd, 0x4c, 0x39, 0x12, 0xf6, 0x7f, 0xb4, 0xa0, 0x99, 0x0c,
0x6c, 0xea, 0x4a, 0xf2, 0xe5, 0x76, 0x39, 0x0a, 0x7f, 0x32, 0x75, 0x89, 0x21, 0x7c, 0xa8, 0x05, 0xa0, 0xc9, 0xdb, 0x50, 0xe0, 0xcb, 0x40, 0x91, 0xaf, 0xf7, 0xeb, 0x49, 0xf8, 0xcb, 0x65, 0x40,
0x79, 0xea, 0x12, 0x0f, 0x33, 0xea, 0xcd, 0x4f, 0xe2, 0x91, 0xf2, 0x18, 0x21, 0x86, 0xe3, 0xfb, 0x1d, 0xe9, 0x43, 0x3d, 0x28, 0xb3, 0x80, 0x86, 0x98, 0xb3, 0x70, 0x7d, 0x12, 0xcf, 0xb5, 0xc7,
0xd8, 0xc5, 0x7d, 0x9b, 0x4d, 0xc5, 0xe5, 0x98, 0xc0, 0xef, 0x2b, 0x8f, 0x11, 0x62, 0xf8, 0x2c, 0x31, 0x18, 0x81, 0x1f, 0xe3, 0x00, 0x8f, 0x3d, 0xbe, 0x94, 0x97, 0x63, 0x06, 0x7f, 0xae, 0x3d,
0x9e, 0x13, 0xcf, 0xb7, 0xa9, 0x23, 0xae, 0xc8, 0xc4, 0x2c, 0x3e, 0x92, 0x0e, 0x23, 0x40, 0xe8, 0x8e, 0xc1, 0x88, 0x59, 0xbc, 0xa1, 0x61, 0xe4, 0x31, 0x5f, 0x5e, 0x91, 0x99, 0x59, 0xfc, 0x50,
0x63, 0xa8, 0xdc, 0xb1, 0x1d, 0xeb, 0x21, 0xc1, 0xde, 0x59, 0xab, 0xf4, 0x3a, 0x64, 0x7d, 0x86, 0x39, 0x9c, 0x18, 0x61, 0xcf, 0xa1, 0xf1, 0xd8, 0xf3, 0xc9, 0x33, 0x8a, 0xc3, 0xbb, 0x56, 0xe9,
0x3d, 0x26, 0x3b, 0xc7, 0x1c, 0x44, 0x3a, 0xa3, 0x36, 0x94, 0x96, 0x67, 0x4f, 0x7c, 0xe8, 0x37, 0xeb, 0x50, 0x8c, 0x38, 0x0e, 0xb9, 0xea, 0x1c, 0x6b, 0x10, 0xe5, 0x4c, 0xda, 0x50, 0x5e, 0x9d,
0xa1, 0x1a, 0x0d, 0xa7, 0x6a, 0x76, 0xfa, 0x41, 0x40, 0x50, 0x3d, 0x98, 0x8c, 0xdd, 0xc4, 0x9d, 0x3d, 0xf9, 0x61, 0x3f, 0x82, 0x66, 0x32, 0x9c, 0xae, 0xd9, 0xed, 0x07, 0x01, 0x41, 0xf3, 0x62,
0xf8, 0x2e, 0xd4, 0x62, 0xb6, 0xd9, 0x54, 0x4b, 0xcf, 0x48, 0x19, 0x4a, 0x47, 0x0c, 0x47, 0x17, 0x31, 0x0f, 0x32, 0x77, 0xe2, 0xa7, 0xd0, 0x4a, 0xd9, 0x56, 0x53, 0x6d, 0x3d, 0x23, 0x75, 0xa8,
0xc7, 0x1f, 0x1a, 0xac, 0x73, 0xc3, 0xd1, 0x64, 0x3c, 0xc6, 0xde, 0x34, 0xcc, 0x74, 0x19, 0x60, 0x5d, 0x71, 0x9c, 0x5c, 0x1c, 0xff, 0xb0, 0x60, 0x5f, 0x18, 0xae, 0x16, 0xf3, 0x39, 0x0e, 0x97,
0xe2, 0x13, 0xcb, 0xf4, 0x5d, 0xdc, 0x27, 0xea, 0xfe, 0x28, 0x70, 0xcb, 0x11, 0x37, 0xa0, 0x2b, 0x26, 0xd3, 0x03, 0x80, 0x45, 0x44, 0x89, 0x1b, 0x05, 0x78, 0x4c, 0xf5, 0xfd, 0x51, 0x11, 0x96,
0x50, 0xc1, 0xcf, 0xb1, 0x3d, 0xe2, 0x17, 0xbe, 0xc2, 0xa4, 0x04, 0xa6, 0x1c, 0x9a, 0x25, 0xf0, 0x2b, 0x61, 0x40, 0x0f, 0xa1, 0x81, 0xdf, 0x60, 0x6f, 0x26, 0x2e, 0x7c, 0x8d, 0xc9, 0x49, 0x4c,
0xff, 0x50, 0x12, 0x79, 0x6c, 0x67, 0x20, 0xf6, 0x95, 0xac, 0x46, 0x91, 0xdb, 0xba, 0xd2, 0xc4, 0xdd, 0x98, 0x15, 0xf0, 0xab, 0x50, 0x93, 0x79, 0x3c, 0x7f, 0x22, 0xf7, 0x95, 0xaa, 0x46, 0x55,
0xfb, 0x9f, 0x80, 0x10, 0x89, 0x90, 0x6d, 0x4d, 0x8c, 0x7e, 0x5b, 0x02, 0xde, 0x80, 0xb2, 0x00, 0xd8, 0x86, 0xca, 0x24, 0xfa, 0x9f, 0x84, 0x50, 0x85, 0x50, 0x6d, 0x4d, 0x8e, 0xfe, 0xb9, 0x02,
0xf4, 0xb0, 0x63, 0x7d, 0x66, 0x5b, 0x6c, 0xa8, 0x3a, 0xd9, 0x1a, 0xb7, 0x76, 0x02, 0x23, 0xda, 0x7c, 0x03, 0xea, 0x12, 0x30, 0xc2, 0x3e, 0xf9, 0xa9, 0x47, 0xf8, 0x54, 0x77, 0xb2, 0x3d, 0x61,
0x85, 0xf5, 0x88, 0x53, 0x84, 0xcd, 0xc9, 0xae, 0x17, 0xba, 0xc2, 0x00, 0x51, 0x56, 0xec, 0x0f, 0x1d, 0xc4, 0x46, 0x74, 0x0a, 0xfb, 0x09, 0xa7, 0x04, 0x5b, 0x52, 0x5d, 0xcf, 0xb8, 0x4c, 0x80,
0x7b, 0x14, 0x7b, 0x56, 0x50, 0x8f, 0x97, 0x19, 0xa8, 0xc5, 0x8c, 0xaa, 0x1a, 0x57, 0x60, 0x95, 0x2c, 0x2b, 0x8e, 0xa6, 0x23, 0x86, 0x43, 0x12, 0xd7, 0xe3, 0x9f, 0x05, 0x68, 0xa5, 0x8c, 0xba,
0x97, 0x6f, 0xf9, 0xf5, 0x9f, 0xe3, 0xee, 0xae, 0x85, 0xae, 0x42, 0x55, 0x00, 0xfb, 0xd4, 0x71, 0x1a, 0x0f, 0x61, 0x57, 0x94, 0x6f, 0xfb, 0xf5, 0x5f, 0x12, 0xee, 0x21, 0x41, 0x1f, 0x42, 0x53,
0x48, 0x9f, 0x0b, 0x1b, 0x5f, 0x15, 0xa6, 0xc2, 0xed, 0xfb, 0x91, 0x19, 0xed, 0x40, 0xad, 0x47, 0x02, 0xc7, 0xcc, 0xf7, 0xe9, 0x58, 0x08, 0x9b, 0x48, 0x17, 0xa6, 0x21, 0xec, 0xe7, 0x89, 0x19,
0x29, 0xf3, 0x99, 0x87, 0x5d, 0x33, 0x38, 0x76, 0x69, 0x71, 0x43, 0x54, 0x43, 0x87, 0x3a, 0x75, 0x9d, 0x40, 0x6b, 0xc4, 0x18, 0x8f, 0x78, 0x88, 0x03, 0x37, 0x3e, 0x76, 0x79, 0x79, 0x43, 0x34,
0x3c, 0xaf, 0xd0, 0x0e, 0x0e, 0x1e, 0x85, 0xd8, 0x8c, 0xc0, 0x56, 0x02, 0x7b, 0x0c, 0x4a, 0x5e, 0x8d, 0x43, 0x9f, 0x3a, 0x91, 0x57, 0x6a, 0x07, 0x1f, 0xcf, 0x0c, 0xb6, 0x20, 0xb1, 0x8d, 0xd8,
0xcc, 0x40, 0xb3, 0x12, 0x1a, 0xd8, 0x03, 0xe8, 0x0e, 0xd4, 0xac, 0x60, 0xae, 0x21, 0x36, 0x27, 0x9e, 0x82, 0xd2, 0xb7, 0x2b, 0xd0, 0xa2, 0x82, 0xc6, 0xf6, 0x18, 0x7a, 0x02, 0x2d, 0x12, 0xcf,
0x29, 0x84, 0x8e, 0x00, 0x7c, 0x53, 0x6c, 0x7b, 0xe6, 0xd7, 0x57, 0xc5, 0xa1, 0xda, 0x8c, 0x35, 0xd5, 0x60, 0x4b, 0x8a, 0x82, 0x71, 0xc4, 0xe0, 0x47, 0x72, 0xdb, 0xf3, 0xa8, 0xbd, 0x2b, 0x0f,
0xd4, 0x05, 0x1b, 0xc8, 0x90, 0x60, 0xf4, 0x0e, 0xe4, 0x26, 0x2e, 0x17, 0x71, 0xf5, 0xbc, 0x08, 0xd5, 0x61, 0xaa, 0xa1, 0x6e, 0xd8, 0x40, 0x8e, 0x02, 0xa3, 0xef, 0x40, 0x69, 0x11, 0x08, 0x11,
0xfb, 0x5f, 0x4b, 0x2a, 0xbc, 0x56, 0xa0, 0xf0, 0x5a, 0x07, 0x4a, 0x01, 0x1a, 0x0a, 0x88, 0x6e, 0xd7, 0x2e, 0xcb, 0xb0, 0xaf, 0xf4, 0x94, 0xc2, 0xeb, 0xc5, 0x0a, 0xaf, 0x77, 0xa1, 0x15, 0xa0,
0x43, 0x51, 0xc8, 0x1d, 0xd7, 0x76, 0x06, 0xc4, 0xaa, 0x17, 0x44, 0x5c, 0x63, 0x2e, 0xee, 0x49, 0xa3, 0x81, 0xe8, 0x73, 0xa8, 0x4a, 0xb9, 0x13, 0x78, 0xfe, 0x84, 0x92, 0x76, 0x45, 0xc6, 0x75,
0xa0, 0x0c, 0x3b, 0x79, 0xbe, 0x18, 0x2f, 0x7f, 0x69, 0x6a, 0x06, 0xf0, 0xc0, 0x43, 0x11, 0x87, 0xd6, 0xe2, 0x5e, 0xc6, 0xca, 0x70, 0x50, 0x16, 0x8b, 0xf1, 0xab, 0xbf, 0x74, 0x2d, 0x07, 0x44,
0xee, 0x42, 0x49, 0xa4, 0x79, 0x36, 0x21, 0x9e, 0x4d, 0xac, 0x3a, 0xfc, 0x8d, 0x3c, 0x82, 0xc0, 0xe0, 0xa5, 0x8c, 0x43, 0x5f, 0x40, 0x4d, 0xa6, 0x79, 0xbd, 0xa0, 0xa1, 0x47, 0x49, 0x1b, 0xfe,
0x63, 0x19, 0xa8, 0x7f, 0xa3, 0xc1, 0x86, 0x12, 0x35, 0xf7, 0x08, 0x1e, 0xb1, 0x61, 0x70, 0x51, 0x83, 0x3c, 0x92, 0xc0, 0x0b, 0x15, 0x88, 0x3e, 0x85, 0x96, 0xe1, 0xe3, 0x5e, 0x87, 0x6c, 0x2e,
0x9c, 0x87, 0x9c, 0xec, 0xfa, 0x4a, 0x09, 0xaa, 0x2f, 0xbe, 0x5f, 0x89, 0xd3, 0xf7, 0xa6, 0x2e, 0xb6, 0x41, 0x55, 0x6e, 0x83, 0x74, 0xf7, 0xac, 0xc7, 0x63, 0x3f, 0x0e, 0xd9, 0x7c, 0x48, 0x8c,
0x23, 0x56, 0x5c, 0x63, 0xae, 0x85, 0x56, 0xae, 0x2e, 0xd1, 0x6b, 0x10, 0x08, 0x41, 0xd3, 0x76, 0xe2, 0x4c, 0xc2, 0xe2, 0x0a, 0xd7, 0x64, 0x85, 0xf7, 0xd3, 0x78, 0x5d, 0x64, 0xfb, 0x37, 0x16,
0x2c, 0xf2, 0x42, 0x9d, 0x8d, 0x92, 0x32, 0x76, 0xb9, 0x8d, 0x9f, 0x43, 0xd7, 0xa3, 0x9f, 0x92, 0x1c, 0x68, 0x01, 0xf5, 0x84, 0xe2, 0x19, 0x9f, 0xc6, 0x97, 0xd2, 0x3d, 0x28, 0x29, 0x85, 0xa1,
0xbe, 0xd0, 0x1e, 0x19, 0x91, 0xa7, 0xa0, 0x2c, 0x5d, 0x4b, 0xff, 0x5e, 0x83, 0xb5, 0x04, 0x37, 0x55, 0xa7, 0xfe, 0x12, 0x67, 0x83, 0xfa, 0xe3, 0x70, 0x19, 0x70, 0x4a, 0xd2, 0x7a, 0x76, 0xcf,
0xb4, 0x03, 0xc5, 0xa1, 0xf8, 0x35, 0x35, 0x79, 0x97, 0xd7, 0xe6, 0xba, 0x3c, 0x28, 0x77, 0xd7, 0x58, 0x85, 0x92, 0x45, 0x5f, 0x83, 0x58, 0x74, 0xba, 0x9e, 0x4f, 0xe8, 0x5b, 0x7d, 0x0e, 0x6b,
0xf2, 0xb9, 0x56, 0x99, 0x38, 0x71, 0xf8, 0xbc, 0x28, 0x28, 0x85, 0x00, 0x1e, 0xb0, 0x03, 0x45, 0xda, 0x38, 0x14, 0x36, 0x71, 0xe6, 0x83, 0x90, 0xfd, 0x84, 0x8e, 0xa5, 0xce, 0x29, 0xc8, 0x3c,
0x7a, 0x7c, 0x3c, 0xb2, 0x1d, 0x22, 0xe0, 0xe9, 0xf9, 0xec, 0xca, 0xcd, 0xc1, 0x75, 0x58, 0x55, 0x15, 0x6d, 0x19, 0x12, 0xfb, 0xf7, 0x16, 0xec, 0x65, 0xb8, 0xa1, 0x13, 0xa8, 0x4e, 0xe5, 0xaf,
0x73, 0x51, 0xc4, 0x83, 0x4f, 0xfd, 0x73, 0x0d, 0xce, 0xcd, 0x94, 0x54, 0x9d, 0xb4, 0xeb, 0x90, 0xa5, 0x2b, 0x14, 0x85, 0xb5, 0xa6, 0x28, 0x40, 0xbb, 0x87, 0x24, 0x12, 0xba, 0x68, 0xe1, 0xa7,
0x93, 0xc3, 0xa9, 0xfe, 0x57, 0x8f, 0x6f, 0xb3, 0x44, 0x84, 0xc2, 0xa1, 0xf7, 0x00, 0x3c, 0x62, 0xe1, 0xeb, 0x02, 0xa4, 0x66, 0x00, 0x22, 0xe0, 0x04, 0xaa, 0xec, 0xfa, 0x7a, 0xe6, 0xf9, 0x54,
0x4d, 0x1c, 0x0b, 0x3b, 0xfd, 0xa9, 0x6a, 0x28, 0x17, 0x63, 0xaa, 0xdb, 0x08, 0x9d, 0x47, 0xfd, 0xc2, 0xf3, 0xeb, 0xd9, 0xb5, 0x5b, 0x80, 0xdb, 0xb0, 0xab, 0xe7, 0xa2, 0x89, 0xc7, 0x9f, 0xf6,
0x21, 0x19, 0x13, 0x23, 0x06, 0xd7, 0x7f, 0xd3, 0x60, 0xfd, 0x51, 0x8f, 0x17, 0x33, 0xb9, 0xb4, 0xcf, 0x2c, 0x78, 0x6f, 0xa5, 0xa4, 0xfa, 0x54, 0x7f, 0x0c, 0x25, 0x35, 0x9c, 0xee, 0xb5, 0xed,
0xf3, 0x4b, 0xa8, 0x2d, 0x5a, 0xc2, 0x68, 0x07, 0xa4, 0x12, 0x3b, 0x20, 0xb9, 0x6a, 0xe9, 0x99, 0xf4, 0x96, 0xce, 0x44, 0x68, 0x1c, 0xfa, 0x2e, 0x40, 0x48, 0xc9, 0xc2, 0x27, 0xd8, 0x1f, 0x2f,
0x55, 0xe3, 0x82, 0x5e, 0x34, 0x09, 0x13, 0x1f, 0x33, 0xe2, 0x99, 0xf1, 0x22, 0xa5, 0x8d, 0x9a, 0x75, 0xf3, 0xfa, 0x20, 0xa5, 0xf0, 0x1d, 0xe3, 0xbc, 0x1a, 0x4f, 0xe9, 0x9c, 0x3a, 0x29, 0xb8,
0x70, 0xed, 0x71, 0x4f, 0xf0, 0xe0, 0x78, 0x0b, 0x10, 0x71, 0x2c, 0xb3, 0x47, 0x8e, 0xa9, 0x47, 0xfd, 0x37, 0x0b, 0xf6, 0x9f, 0x8f, 0x44, 0x31, 0xb3, 0x4b, 0xbb, 0xbe, 0x84, 0xd6, 0xa6, 0x25,
0x42, 0xb8, 0xbc, 0x04, 0xab, 0xc4, 0xb1, 0x3a, 0xc2, 0x11, 0xa0, 0xc3, 0xce, 0x93, 0x8b, 0x3d, 0x4c, 0x76, 0x40, 0x2e, 0xb3, 0x03, 0xb2, 0xab, 0x96, 0x5f, 0x59, 0x35, 0xf1, 0x78, 0x90, 0x0d,
0x80, 0xf4, 0x2f, 0x35, 0xd8, 0x48, 0xce, 0x54, 0x55, 0xfc, 0xe6, 0x9c, 0xb0, 0x5f, 0x5e, 0xf3, 0xc9, 0xc5, 0xd7, 0x9c, 0x86, 0x6e, 0xba, 0x48, 0x79, 0xa7, 0x25, 0x5d, 0x67, 0xc2, 0x13, 0x3f,
0x10, 0xf9, 0x8f, 0xaa, 0xde, 0xfe, 0x2a, 0x03, 0xa5, 0xfb, 0xd8, 0xea, 0x06, 0xa3, 0xa0, 0x2e, 0x6e, 0xbe, 0x05, 0x88, 0xfa, 0xc4, 0x1d, 0xd1, 0x6b, 0x16, 0x52, 0x03, 0x57, 0x17, 0x6e, 0x93,
0x40, 0xa4, 0xfa, 0xd1, 0xa5, 0xd8, 0xf8, 0x73, 0x8f, 0x81, 0xc6, 0xe5, 0x25, 0x5e, 0x35, 0x9d, 0xfa, 0x64, 0x20, 0x1d, 0x31, 0xda, 0x74, 0xb9, 0x52, 0xea, 0xb1, 0x65, 0xff, 0xc2, 0x82, 0x83,
0x7d, 0xc8, 0x07, 0xba, 0x0d, 0x35, 0x62, 0xd0, 0x19, 0x65, 0xd8, 0xb8, 0xb8, 0xd0, 0xa7, 0x92, 0xec, 0x4c, 0x75, 0xc5, 0x1f, 0xad, 0x3d, 0x22, 0xb6, 0xd7, 0xdc, 0x20, 0xff, 0xab, 0xaa, 0xf7,
0x74, 0x01, 0x22, 0x65, 0x96, 0xe0, 0x33, 0xa7, 0xf7, 0x12, 0x7c, 0x16, 0xc8, 0xb9, 0x7d, 0xc8, 0x7f, 0x59, 0x80, 0xda, 0x97, 0x98, 0x0c, 0xe3, 0x51, 0xd0, 0x10, 0x20, 0x79, 0x61, 0xa0, 0xfb,
0x07, 0x2a, 0x29, 0xc1, 0x67, 0x46, 0x9b, 0x25, 0xf8, 0xcc, 0xc9, 0xaa, 0x7d, 0xc8, 0x07, 0xb2, 0xa9, 0xf1, 0xd7, 0x1e, 0x1e, 0x9d, 0x07, 0x5b, 0xbc, 0x7a, 0x3a, 0xe7, 0x50, 0x8e, 0x35, 0x22,
0x21, 0x91, 0x64, 0x46, 0xba, 0x24, 0x92, 0xcc, 0xe9, 0x8c, 0x3b, 0x50, 0x08, 0x15, 0x03, 0x8a, 0xea, 0xa4, 0xa0, 0x2b, 0x2a, 0xb4, 0xf3, 0xc1, 0x46, 0x9f, 0x4e, 0x32, 0x04, 0x48, 0x54, 0x60,
0x23, 0x67, 0xb5, 0x45, 0xe3, 0xd2, 0x62, 0xa7, 0xca, 0x63, 0xc0, 0x5a, 0xe2, 0x05, 0x85, 0x9a, 0x86, 0xcf, 0x9a, 0xb6, 0xcc, 0xf0, 0xd9, 0x20, 0x1d, 0xcf, 0xa1, 0x1c, 0x2b, 0xb2, 0x0c, 0x9f,
0xcb, 0xdf, 0x56, 0x32, 0xdf, 0xd6, 0x69, 0x8f, 0xaf, 0xf6, 0x77, 0x1a, 0x54, 0x1f, 0x3d, 0x27, 0x15, 0x1d, 0x98, 0xe1, 0xb3, 0x26, 0xe1, 0xce, 0xa1, 0x1c, 0x4b, 0x94, 0x4c, 0x92, 0x15, 0x99,
0xde, 0x08, 0x4f, 0xff, 0x93, 0x5d, 0xf1, 0x2f, 0xcd, 0xbd, 0xfd, 0xad, 0x06, 0xeb, 0xe2, 0x55, 0x94, 0x49, 0xb2, 0xa6, 0x69, 0x1e, 0x43, 0xc5, 0xa8, 0x13, 0x94, 0x46, 0xae, 0xea, 0x98, 0xce,
0x7e, 0xc4, 0xa8, 0x47, 0x22, 0xaa, 0x1d, 0xc8, 0x0a, 0x59, 0x85, 0x2e, 0xcc, 0xb4, 0xc5, 0x30, 0xfd, 0xcd, 0x4e, 0x9d, 0xc7, 0x81, 0xbd, 0xcc, 0x6b, 0x0d, 0x75, 0xb7, 0xbf, 0xe3, 0x54, 0xbe,
0xef, 0x29, 0xfd, 0x52, 0x5f, 0x41, 0xf7, 0xa0, 0x10, 0x2a, 0x8f, 0x24, 0xc7, 0x19, 0x91, 0x92, 0xa3, 0xdb, 0x1e, 0x7a, 0xfd, 0xdf, 0x59, 0xd0, 0x7c, 0xfe, 0x86, 0x86, 0x33, 0xbc, 0xfc, 0xbf,
0xe4, 0x38, 0x2b, 0x56, 0xf4, 0x95, 0xf6, 0x17, 0x1a, 0x6c, 0xc4, 0x5e, 0xe4, 0x11, 0x4d, 0x17, 0xec, 0x8a, 0xff, 0xd1, 0xdc, 0xfb, 0xbf, 0xb5, 0x60, 0x5f, 0xfe, 0x03, 0x70, 0xc5, 0x59, 0x48,
0x2e, 0x2c, 0x79, 0xe7, 0xa3, 0xab, 0xf1, 0x6d, 0xfc, 0x97, 0xff, 0xb0, 0x34, 0xae, 0x9d, 0x05, 0x13, 0xaa, 0x03, 0x28, 0x4a, 0x09, 0x87, 0xde, 0x5f, 0x69, 0xc1, 0x26, 0xef, 0x2d, 0xbd, 0xd9,
0xaa, 0x0a, 0xf6, 0x83, 0x06, 0x15, 0x79, 0x79, 0x44, 0x2c, 0x1e, 0x43, 0x29, 0x7e, 0x13, 0xa1, 0xde, 0x41, 0x4f, 0xa0, 0x62, 0x54, 0x4e, 0x96, 0xe3, 0x8a, 0x20, 0xca, 0x72, 0x5c, 0x15, 0x46,
0x78, 0x69, 0x16, 0x5c, 0xc6, 0x8d, 0xe6, 0x52, 0x7f, 0x58, 0xbb, 0x27, 0xb3, 0x6d, 0xb0, 0xb9, 0xf6, 0x4e, 0xff, 0xe7, 0x16, 0x1c, 0xa4, 0x5e, 0xff, 0x09, 0xcd, 0x00, 0xde, 0xdf, 0xf2, 0x9f,
0xf4, 0x0e, 0x5b, 0xb0, 0x27, 0x17, 0xb6, 0x22, 0x7d, 0xa5, 0x93, 0xf9, 0x38, 0xe5, 0xf6, 0x7a, 0x02, 0xfa, 0x30, 0xbd, 0x8d, 0xff, 0xed, 0xbf, 0x39, 0x9d, 0x8f, 0xee, 0x02, 0xd5, 0x05, 0xfb,
0x39, 0x21, 0x15, 0x6e, 0xfc, 0x19, 0x00, 0x00, 0xff, 0xff, 0xcf, 0xfc, 0x21, 0xfe, 0x01, 0x13, 0x83, 0x05, 0x0d, 0x75, 0x79, 0x24, 0x2c, 0x5e, 0x40, 0x2d, 0x7d, 0x13, 0xa1, 0x74, 0x69, 0x36,
0x00, 0x00, 0x5c, 0xc6, 0x9d, 0xee, 0x56, 0xbf, 0xa9, 0xdd, 0xcb, 0xd5, 0x36, 0xd8, 0xdd, 0x7a, 0x87, 0x6d,
0xd8, 0x93, 0x1b, 0x5b, 0x91, 0xbd, 0x33, 0x28, 0xfc, 0x28, 0x17, 0x8c, 0x46, 0x25, 0x29, 0x4b,
0x3e, 0xf9, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x55, 0xd5, 0x03, 0xf3, 0x6d, 0x13, 0x00, 0x00,
} }
type DRPCKadInspectorClient interface { type DRPCKadInspectorClient interface {

View File

@ -189,6 +189,8 @@ message DashboardResponse {
google.protobuf.Duration uptime = 8; google.protobuf.Duration uptime = 8;
google.protobuf.Timestamp last_pinged = 9 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; google.protobuf.Timestamp last_pinged = 9 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
google.protobuf.Timestamp last_queried = 10 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false]; google.protobuf.Timestamp last_queried = 10 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
bytes last_ping_from_id = 11 [(gogoproto.customtype) = "NodeID"];
string last_ping_from_address = 12;
} }
message SegmentHealthRequest { message SegmentHealthRequest {

View File

@ -1348,6 +1348,22 @@
"value": "false" "value": "false"
} }
] ]
},
{
"id": 11,
"name": "last_ping_from_id",
"type": "bytes",
"options": [
{
"name": "(gogoproto.customtype)",
"value": "NodeID"
}
]
},
{
"id": 12,
"name": "last_ping_from_address",
"type": "string"
} }
] ]
}, },

View File

@ -357,7 +357,7 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten
return nil, errs.Combine(err, peer.Close()) return nil, errs.Combine(err, peer.Close())
} }
peer.Kademlia.Endpoint = kademlia.NewEndpoint(peer.Log.Named("kademlia:endpoint"), peer.Kademlia.Service, peer.Kademlia.RoutingTable, nil) peer.Kademlia.Endpoint = kademlia.NewEndpoint(peer.Log.Named("kademlia:endpoint"), peer.Kademlia.Service, nil, peer.Kademlia.RoutingTable, nil)
pb.RegisterNodesServer(peer.Server.GRPC(), peer.Kademlia.Endpoint) pb.RegisterNodesServer(peer.Server.GRPC(), peer.Kademlia.Endpoint)
peer.Kademlia.Inspector = kademlia.NewInspector(peer.Kademlia.Service, peer.Identity) peer.Kademlia.Inspector = kademlia.NewInspector(peer.Kademlia.Service, peer.Identity)

View File

@ -14,9 +14,9 @@ import (
"storj.io/storj/internal/date" "storj.io/storj/internal/date"
"storj.io/storj/internal/memory" "storj.io/storj/internal/memory"
"storj.io/storj/internal/version" "storj.io/storj/internal/version"
"storj.io/storj/pkg/kademlia"
"storj.io/storj/pkg/storj" "storj.io/storj/pkg/storj"
"storj.io/storj/storagenode/bandwidth" "storj.io/storj/storagenode/bandwidth"
"storj.io/storj/storagenode/contact"
"storj.io/storj/storagenode/pieces" "storj.io/storj/storagenode/pieces"
"storj.io/storj/storagenode/reputation" "storj.io/storj/storagenode/reputation"
"storj.io/storj/storagenode/storageusage" "storj.io/storj/storagenode/storageusage"
@ -41,20 +41,21 @@ type Service struct {
reputationDB reputation.DB reputationDB reputation.DB
storageUsageDB storageusage.DB storageUsageDB storageusage.DB
pieceStore *pieces.Store pieceStore *pieces.Store
kademlia *kademlia.Kademlia
version *version.Service version *version.Service
pingStats *contact.PingStats
allocatedBandwidth memory.Size allocatedBandwidth memory.Size
allocatedDiskSpace memory.Size allocatedDiskSpace memory.Size
nodeID storj.NodeID
walletAddress string walletAddress string
startedAt time.Time startedAt time.Time
versionInfo version.Info versionInfo version.Info
} }
// NewService returns new instance of Service. // NewService returns new instance of Service.
func NewService(log *zap.Logger, bandwidth bandwidth.DB, pieceStore *pieces.Store, kademlia *kademlia.Kademlia, version *version.Service, func NewService(log *zap.Logger, bandwidth bandwidth.DB, pieceStore *pieces.Store, version *version.Service,
allocatedBandwidth, allocatedDiskSpace memory.Size, walletAddress string, versionInfo version.Info, trust *trust.Pool, allocatedBandwidth, allocatedDiskSpace memory.Size, walletAddress string, versionInfo version.Info, trust *trust.Pool,
reputationDB reputation.DB, storageUsageDB storageusage.DB) (*Service, error) { reputationDB reputation.DB, storageUsageDB storageusage.DB, pingStats *contact.PingStats, myNodeID storj.NodeID) (*Service, error) {
if log == nil { if log == nil {
return nil, errs.New("log can't be nil") return nil, errs.New("log can't be nil")
} }
@ -71,8 +72,8 @@ func NewService(log *zap.Logger, bandwidth bandwidth.DB, pieceStore *pieces.Stor
return nil, errs.New("version can't be nil") return nil, errs.New("version can't be nil")
} }
if kademlia == nil { if pingStats == nil {
return nil, errs.New("kademlia can't be nil") return nil, errs.New("pingStats can't be nil")
} }
return &Service{ return &Service{
@ -82,10 +83,11 @@ func NewService(log *zap.Logger, bandwidth bandwidth.DB, pieceStore *pieces.Stor
reputationDB: reputationDB, reputationDB: reputationDB,
storageUsageDB: storageUsageDB, storageUsageDB: storageUsageDB,
pieceStore: pieceStore, pieceStore: pieceStore,
kademlia: kademlia,
version: version, version: version,
pingStats: pingStats,
allocatedBandwidth: allocatedBandwidth, allocatedBandwidth: allocatedBandwidth,
allocatedDiskSpace: allocatedDiskSpace, allocatedDiskSpace: allocatedDiskSpace,
nodeID: myNodeID,
walletAddress: walletAddress, walletAddress: walletAddress,
startedAt: time.Now(), startedAt: time.Now(),
versionInfo: versionInfo, versionInfo: versionInfo,
@ -108,8 +110,9 @@ type Dashboard struct {
DiskSpace DiskSpaceInfo `json:"diskSpace"` DiskSpace DiskSpaceInfo `json:"diskSpace"`
Bandwidth BandwidthInfo `json:"bandwidth"` Bandwidth BandwidthInfo `json:"bandwidth"`
LastPinged time.Time `json:"lastPinged"` LastPinged time.Time `json:"lastPinged"`
LastQueried time.Time `json:"lastQueried"` LastPingFromID storj.NodeID `json:"lastPingFromID"`
LastPingFromAddress string `json:"lastPingFromAddress"`
Version version.SemVer `json:"version"` Version version.SemVer `json:"version"`
UpToDate bool `json:"upToDate"` UpToDate bool `json:"upToDate"`
@ -120,12 +123,12 @@ func (s *Service) GetDashboardData(ctx context.Context) (_ *Dashboard, err error
defer mon.Task()(&ctx)(&err) defer mon.Task()(&ctx)(&err)
data := new(Dashboard) data := new(Dashboard)
data.NodeID = s.kademlia.Local().Id data.NodeID = s.nodeID
data.Wallet = s.walletAddress data.Wallet = s.walletAddress
data.Version = s.versionInfo.Version data.Version = s.versionInfo.Version
data.UpToDate = s.version.IsAllowed() data.UpToDate = s.version.IsAllowed()
data.LastPinged = s.kademlia.LastPinged()
data.LastQueried = s.kademlia.LastQueried() data.LastPinged, data.LastPingFromID, data.LastPingFromAddress = s.pingStats.WhenLastPinged()
stats, err := s.reputationDB.All(ctx) stats, err := s.reputationDB.All(ctx)
if err != nil { if err != nil {

View File

@ -54,7 +54,7 @@ func (endpoint *Endpoint) PingNode(ctx context.Context, req *pb.ContactPingReque
return nil, status.Error(codes.Unauthenticated, err.Error()) return nil, status.Error(codes.Unauthenticated, err.Error())
} }
endpoint.log.Debug("pinged", zap.Stringer("by", peerID.ID), zap.Stringer("srcAddr", p.Addr)) endpoint.log.Debug("pinged", zap.Stringer("by", peerID.ID), zap.Stringer("srcAddr", p.Addr))
endpoint.pingStats.wasPinged(time.Now(), peerID.ID, p.Addr.String()) endpoint.pingStats.WasPinged(time.Now(), peerID.ID, p.Addr.String())
return &pb.ContactPingResponse{}, nil return &pb.ContactPingResponse{}, nil
} }
@ -65,8 +65,8 @@ func (stats *PingStats) WhenLastPinged() (when time.Time, who storj.NodeID, addr
return stats.lastPinged, stats.whoPingedNodeID, stats.whoPingedAddress return stats.lastPinged, stats.whoPingedNodeID, stats.whoPingedAddress
} }
// wasPinged notifies the service it has been remotely pinged. // WasPinged notifies the service it has been remotely pinged.
func (stats *PingStats) wasPinged(when time.Time, srcNodeID storj.NodeID, srcAddress string) { func (stats *PingStats) WasPinged(when time.Time, srcNodeID storj.NodeID, srcAddress string) {
stats.mu.Lock() stats.mu.Lock()
defer stats.mu.Unlock() defer stats.mu.Unlock()
stats.lastPinged = when stats.lastPinged = when

View File

@ -18,6 +18,7 @@ import (
"storj.io/storj/pkg/pb" "storj.io/storj/pkg/pb"
"storj.io/storj/pkg/storj" "storj.io/storj/pkg/storj"
"storj.io/storj/storagenode/bandwidth" "storj.io/storj/storagenode/bandwidth"
"storj.io/storj/storagenode/contact"
"storj.io/storj/storagenode/pieces" "storj.io/storj/storagenode/pieces"
"storj.io/storj/storagenode/piecestore" "storj.io/storj/storagenode/piecestore"
) )
@ -36,6 +37,7 @@ type Endpoint struct {
log *zap.Logger log *zap.Logger
pieceStore *pieces.Store pieceStore *pieces.Store
kademlia *kademlia.Kademlia kademlia *kademlia.Kademlia
pingStats *contact.PingStats
usageDB bandwidth.DB usageDB bandwidth.DB
startTime time.Time startTime time.Time
@ -48,6 +50,7 @@ func NewEndpoint(
log *zap.Logger, log *zap.Logger,
pieceStore *pieces.Store, pieceStore *pieces.Store,
kademlia *kademlia.Kademlia, kademlia *kademlia.Kademlia,
pingStats *contact.PingStats,
usageDB bandwidth.DB, usageDB bandwidth.DB,
pieceStoreConfig piecestore.OldConfig, pieceStoreConfig piecestore.OldConfig,
dashbaordAddress net.Addr) *Endpoint { dashbaordAddress net.Addr) *Endpoint {
@ -56,6 +59,7 @@ func NewEndpoint(
log: log, log: log,
pieceStore: pieceStore, pieceStore: pieceStore,
kademlia: kademlia, kademlia: kademlia,
pingStats: pingStats,
usageDB: usageDB, usageDB: usageDB,
pieceStoreConfig: pieceStoreConfig, pieceStoreConfig: pieceStoreConfig,
dashboardAddress: dashbaordAddress, dashboardAddress: dashbaordAddress,
@ -126,17 +130,20 @@ func (inspector *Endpoint) getDashboardData(ctx context.Context) (_ *pb.Dashboar
bsNodes[i] = node.Address.Address bsNodes[i] = node.Address.Address
} }
lastPingedAt, lastPingFromID, lastPingFromAddress := inspector.pingStats.WhenLastPinged()
return &pb.DashboardResponse{ return &pb.DashboardResponse{
NodeId: inspector.kademlia.Local().Id, NodeId: inspector.kademlia.Local().Id,
NodeConnections: int64(len(nodes)), NodeConnections: int64(len(nodes)),
BootstrapAddress: strings.Join(bsNodes, ", "), BootstrapAddress: strings.Join(bsNodes, ", "),
InternalAddress: "", InternalAddress: "",
ExternalAddress: inspector.kademlia.Local().Address.Address, ExternalAddress: inspector.kademlia.Local().Address.Address,
LastPinged: inspector.kademlia.LastPinged(), LastPinged: lastPingedAt,
LastQueried: inspector.kademlia.LastQueried(), LastPingFromId: &lastPingFromID,
DashboardAddress: inspector.dashboardAddress.String(), LastPingFromAddress: lastPingFromAddress,
Uptime: ptypes.DurationProto(time.Since(inspector.startTime)), DashboardAddress: inspector.dashboardAddress.String(),
Stats: statsSummary, Uptime: ptypes.DurationProto(time.Since(inspector.startTime)),
Stats: statsSummary,
}, nil }, nil
} }

View File

@ -70,7 +70,7 @@ func TestInspectorStats(t *testing.T) {
// TODO set more accurate assertions // TODO set more accurate assertions
if response.UsedSpace > 0 { if response.UsedSpace > 0 {
assert.True(t, response.UsedBandwidth > 0) assert.NotZero(t, response.UsedBandwidth)
assert.Equal(t, response.UsedBandwidth, response.UsedIngress+response.UsedEgress) assert.Equal(t, response.UsedBandwidth, response.UsedIngress+response.UsedEgress)
assert.Equal(t, availableBandwidth-response.UsedBandwidth, response.AvailableBandwidth) assert.Equal(t, availableBandwidth-response.UsedBandwidth, response.AvailableBandwidth)
assert.Equal(t, availableSpace-response.UsedSpace, response.AvailableSpace) assert.Equal(t, availableSpace-response.UsedSpace, response.AvailableSpace)
@ -87,7 +87,7 @@ func TestInspectorStats(t *testing.T) {
assert.Equal(t, availableSpace, response.AvailableSpace) assert.Equal(t, availableSpace, response.AvailableSpace)
} }
} }
assert.True(t, downloaded >= rs.MinThreshold) assert.True(t, downloaded >= rs.MinThreshold, "downloaded=%v, rs.MinThreshold=%v", downloaded, rs.MinThreshold)
} }
func TestInspectorDashboard(t *testing.T) { func TestInspectorDashboard(t *testing.T) {
@ -116,8 +116,7 @@ func TestInspectorDashboard(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
assert.True(t, response.LastPinged.After(testStartedTime)) assert.True(t, response.LastPinged.After(testStartedTime))
assert.NotEmpty(t, response.LastPingFromAddress)
assert.True(t, response.LastQueried.After(testStartedTime))
assert.True(t, response.Uptime.Nanos > 0) assert.True(t, response.Uptime.Nanos > 0)
assert.Equal(t, storageNode.ID(), response.NodeId) assert.Equal(t, storageNode.ID(), response.NodeId)

View File

@ -202,6 +202,11 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten
} }
} }
// Set up Contact.PingStats before Kademlia (until Kademlia goes away, at which point this can
// be folded back in with the Contact setup block). Both services must share pointers to this
// PingStats instance for now.
peer.Contact.PingStats = &contact.PingStats{}
{ // setup kademlia { // setup kademlia
config := config.Kademlia config := config.Kademlia
// TODO: move this setup logic into kademlia package // TODO: move this setup logic into kademlia package
@ -243,7 +248,7 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten
return nil, errs.Combine(err, peer.Close()) return nil, errs.Combine(err, peer.Close())
} }
peer.Kademlia.Endpoint = kademlia.NewEndpoint(peer.Log.Named("kademlia:endpoint"), peer.Kademlia.Service, peer.Kademlia.RoutingTable, peer.Storage2.Trust) peer.Kademlia.Endpoint = kademlia.NewEndpoint(peer.Log.Named("kademlia:endpoint"), peer.Kademlia.Service, peer.Contact.PingStats, peer.Kademlia.RoutingTable, peer.Storage2.Trust)
pb.RegisterNodesServer(peer.Server.GRPC(), peer.Kademlia.Endpoint) pb.RegisterNodesServer(peer.Server.GRPC(), peer.Kademlia.Endpoint)
peer.Kademlia.Inspector = kademlia.NewInspector(peer.Kademlia.Service, peer.Identity) peer.Kademlia.Inspector = kademlia.NewInspector(peer.Kademlia.Service, peer.Identity)
@ -251,7 +256,6 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten
} }
{ // setup contact service { // setup contact service
peer.Contact.PingStats = new(contact.PingStats)
peer.Contact.Chore = contact.NewChore(peer.Log.Named("contact:chore"), config.Contact.Interval, config.Contact.MaxSleep, peer.Storage2.Trust, peer.Transport, peer.Kademlia.RoutingTable) peer.Contact.Chore = contact.NewChore(peer.Log.Named("contact:chore"), config.Contact.Interval, config.Contact.MaxSleep, peer.Storage2.Trust, peer.Transport, peer.Kademlia.RoutingTable)
peer.Contact.Endpoint = contact.NewEndpoint(peer.Log.Named("contact:endpoint"), peer.Contact.PingStats) peer.Contact.Endpoint = contact.NewEndpoint(peer.Log.Named("contact:endpoint"), peer.Contact.PingStats)
pb.RegisterContactServer(peer.Server.GRPC(), peer.Contact.Endpoint) pb.RegisterContactServer(peer.Server.GRPC(), peer.Contact.Endpoint)
@ -352,7 +356,6 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten
peer.Log.Named("console:service"), peer.Log.Named("console:service"),
peer.DB.Bandwidth(), peer.DB.Bandwidth(),
peer.Storage2.Store, peer.Storage2.Store,
peer.Kademlia.Service,
peer.Version, peer.Version,
config.Storage.AllocatedBandwidth, config.Storage.AllocatedBandwidth,
config.Storage.AllocatedDiskSpace, config.Storage.AllocatedDiskSpace,
@ -360,7 +363,9 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten
versionInfo, versionInfo,
peer.Storage2.Trust, peer.Storage2.Trust,
peer.DB.Reputation(), peer.DB.Reputation(),
peer.DB.StorageUsage()) peer.DB.StorageUsage(),
peer.Contact.PingStats,
peer.Local().Id)
if err != nil { if err != nil {
return nil, errs.Combine(err, peer.Close()) return nil, errs.Combine(err, peer.Close())
@ -384,6 +389,7 @@ func New(log *zap.Logger, full *identity.FullIdentity, db DB, revocationDB exten
peer.Log.Named("pieces:inspector"), peer.Log.Named("pieces:inspector"),
peer.Storage2.Store, peer.Storage2.Store,
peer.Kademlia.Service, peer.Kademlia.Service,
peer.Contact.PingStats,
peer.DB.Bandwidth(), peer.DB.Bandwidth(),
config.Storage, config.Storage,
peer.Console.Listener.Addr(), peer.Console.Listener.Addr(),

View File

@ -43,7 +43,7 @@ export class SNOApi {
const bandwidth: BandwidthInfo = new BandwidthInfo(json.bandwidth.used, json.bandwidth.available); const bandwidth: BandwidthInfo = new BandwidthInfo(json.bandwidth.used, json.bandwidth.available);
return new Dashboard(json.nodeID, json.wallet, satellites, diskSpace, bandwidth, return new Dashboard(json.nodeID, json.wallet, satellites, diskSpace, bandwidth,
new Date(json.lastPinged), new Date(json.lastQueried), version, json.upToDate); new Date(json.lastPinged), version, json.upToDate);
} }
/** /**

View File

@ -12,7 +12,6 @@ export class Dashboard {
public diskSpace: DiskSpaceInfo, public diskSpace: DiskSpaceInfo,
public bandwidth: BandwidthInfo, public bandwidth: BandwidthInfo,
public lastPinged: Date, public lastPinged: Date,
public lastQueried: Date,
public version: Version, public version: Version,
public isUpToDate: boolean) {} public isUpToDate: boolean) {}
} }