satellite/satellitedb/heldamount added, endpoint added
Change-Id: Ife8402b89f631f65ebb5cdf5ca02e99aa9b0b3ff
This commit is contained in:
parent
988bb52855
commit
94c4d1e737
138
satellite/heldamount/endpoint.go
Normal file
138
satellite/heldamount/endpoint.go
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
// Copyright (C) 2020 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
package heldamount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/spacemonkeygo/monkit/v3"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"storj.io/common/identity"
|
||||||
|
"storj.io/common/pb"
|
||||||
|
"storj.io/common/rpc/rpcstatus"
|
||||||
|
"storj.io/storj/satellite/accounting"
|
||||||
|
"storj.io/storj/satellite/overlay"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
mon = monkit.Package()
|
||||||
|
)
|
||||||
|
|
||||||
|
// Endpoint for querying node stats for the SNO
|
||||||
|
//
|
||||||
|
// architecture: Endpoint
|
||||||
|
type Endpoint struct {
|
||||||
|
service *Service
|
||||||
|
log *zap.Logger
|
||||||
|
overlay overlay.DB
|
||||||
|
accounting accounting.StoragenodeAccounting
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEndpoint creates new endpoint
|
||||||
|
func NewEndpoint(log *zap.Logger, accounting accounting.StoragenodeAccounting, overlay overlay.DB, service *Service) *Endpoint {
|
||||||
|
return &Endpoint{
|
||||||
|
log: log,
|
||||||
|
accounting: accounting,
|
||||||
|
overlay: overlay,
|
||||||
|
service: service,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPayStub sends node paystub for client node.
|
||||||
|
func (e *Endpoint) GetPayStub(ctx context.Context, req *pb.GetHeldAmountRequest) (_ *pb.GetHeldAmountResponse, err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
|
peer, err := identity.PeerIdentityFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, rpcstatus.Error(rpcstatus.Unauthenticated, err.Error())
|
||||||
|
}
|
||||||
|
node, err := e.overlay.Get(ctx, peer.ID)
|
||||||
|
if err != nil {
|
||||||
|
if overlay.ErrNodeNotFound.Has(err) {
|
||||||
|
return nil, rpcstatus.Error(rpcstatus.PermissionDenied, err.Error())
|
||||||
|
}
|
||||||
|
e.log.Error("overlay.Get failed", zap.Error(err))
|
||||||
|
return nil, rpcstatus.Error(rpcstatus.Internal, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
stub, err := e.service.GetPayStub(ctx, node.Id, req.Period.String())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
periodTime, err := toTime(stub.Period)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.GetHeldAmountResponse{
|
||||||
|
Period: periodTime,
|
||||||
|
NodeId: stub.NodeID,
|
||||||
|
CreatedAt: stub.Created,
|
||||||
|
Codes: stub.Codes,
|
||||||
|
UsageAtRest: float32(stub.UsageAtRest),
|
||||||
|
UsageGet: stub.UsageGet,
|
||||||
|
UsagePut: stub.UsagePut,
|
||||||
|
UsageGetRepair: stub.UsageGetRepair,
|
||||||
|
UsagePutRepair: stub.UsagePutRepair,
|
||||||
|
UsageGetAudit: stub.UsageGetAudit,
|
||||||
|
CompAtRest: stub.CompAtRest,
|
||||||
|
CompGet: stub.CompGet,
|
||||||
|
CompPut: stub.CompPut,
|
||||||
|
CompGetRepair: stub.CompGetRepair,
|
||||||
|
CompPutRepair: stub.CompPutRepair,
|
||||||
|
CompGetAudit: stub.CompGetAudit,
|
||||||
|
SurgePercent: stub.SurgePercent,
|
||||||
|
Held: stub.Held,
|
||||||
|
Owed: stub.Owed,
|
||||||
|
Disposed: stub.Disposed,
|
||||||
|
Paid: stub.Paid,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPayment sends node payment data for client node.
|
||||||
|
func (e *Endpoint) GetPayment(ctx context.Context, req *pb.GetPaymentRequest) (_ *pb.GetPaymentResponse, err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
|
peer, err := identity.PeerIdentityFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, rpcstatus.Error(rpcstatus.Unauthenticated, err.Error())
|
||||||
|
}
|
||||||
|
node, err := e.overlay.Get(ctx, peer.ID)
|
||||||
|
if err != nil {
|
||||||
|
if overlay.ErrNodeNotFound.Has(err) {
|
||||||
|
return nil, rpcstatus.Error(rpcstatus.PermissionDenied, err.Error())
|
||||||
|
}
|
||||||
|
e.log.Error("overlay.Get failed", zap.Error(err))
|
||||||
|
return nil, rpcstatus.Error(rpcstatus.Internal, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
payment, err := e.service.GetPayment(ctx, node.Id, req.Period.String())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pb.GetPaymentResponse{
|
||||||
|
NodeId: payment.NodeID,
|
||||||
|
CreatedAt: payment.Created,
|
||||||
|
Period: payment.Period,
|
||||||
|
Amount: payment.Amount,
|
||||||
|
Receipt: payment.Receipt,
|
||||||
|
Notes: payment.Notes,
|
||||||
|
Id: payment.ID,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// toTime converts string period to time.Time.
|
||||||
|
func toTime(period string) (_ time.Time, err error) {
|
||||||
|
const layout = "2006-01"
|
||||||
|
t, err := time.Parse(layout, period)
|
||||||
|
if err != nil {
|
||||||
|
return time.Time{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return t, nil
|
||||||
|
}
|
95
satellite/heldamount/heldamount.go
Normal file
95
satellite/heldamount/heldamount.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Copyright (C) 2020 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
package heldamount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"storj.io/common/storj"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DB exposes all needed functionality to manage heldAmount.
|
||||||
|
//
|
||||||
|
// architecture: Service
|
||||||
|
type DB interface {
|
||||||
|
// GetPaystub return payStub by nodeID and period.
|
||||||
|
GetPaystub(ctx context.Context, nodeID storj.NodeID, period string) (PayStub, error)
|
||||||
|
// GetPayment return storagenode payment by nodeID and period.
|
||||||
|
GetPayment(ctx context.Context, nodeID storj.NodeID, period string) (StoragenodePayment, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PayStub is an entity that holds held amount of cash that will be paid to storagenode operator after some period.
|
||||||
|
type PayStub struct {
|
||||||
|
Period string `json:"period"`
|
||||||
|
NodeID storj.NodeID `json:"nodeId"`
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
Codes string `json:"codes"`
|
||||||
|
UsageAtRest float64 `json:"usageAtRest"`
|
||||||
|
UsageGet int64 `json:"usageGet"`
|
||||||
|
UsagePut int64 `json:"usagePut"`
|
||||||
|
UsageGetRepair int64 `json:"usageGetRepair"`
|
||||||
|
UsagePutRepair int64 `json:"usagePutRepair"`
|
||||||
|
UsageGetAudit int64 `json:"usageGetAudit"`
|
||||||
|
CompAtRest int64 `json:"compAtRest"`
|
||||||
|
CompGet int64 `json:"compGet"`
|
||||||
|
CompPut int64 `json:"compPut"`
|
||||||
|
CompGetRepair int64 `json:"compGetRepair"`
|
||||||
|
CompPutRepair int64 `json:"compPutRepair"`
|
||||||
|
CompGetAudit int64 `json:"compGetAudit"`
|
||||||
|
SurgePercent int64 `json:"surgePercent"`
|
||||||
|
Held int64 `json:"held"`
|
||||||
|
Owed int64 `json:"owed"`
|
||||||
|
Disposed int64 `json:"disposed"`
|
||||||
|
Paid int64 `json:"paid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// StoragenodePayment is an entity that holds payment to storagenode operator parameters.
|
||||||
|
type StoragenodePayment struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
NodeID storj.NodeID `json:"nodeId"`
|
||||||
|
Period time.Time `json:"period"`
|
||||||
|
Amount int64 `json:"amount"`
|
||||||
|
Receipt string `json:"receipt"`
|
||||||
|
Notes string `json:"notes"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Service is used to store and handle node paystub information
|
||||||
|
//
|
||||||
|
// architecture: Service
|
||||||
|
type Service struct {
|
||||||
|
log *zap.Logger
|
||||||
|
db DB
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewService returns a new Service
|
||||||
|
func NewService(log *zap.Logger, db DB) *Service {
|
||||||
|
return &Service{
|
||||||
|
log: log,
|
||||||
|
db: db,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPayStub returns PayStub by nodeID and period.
|
||||||
|
func (service *Service) GetPayStub(ctx context.Context, nodeID storj.NodeID, period string) (PayStub, error) {
|
||||||
|
payStub, err := service.db.GetPaystub(ctx, nodeID, period)
|
||||||
|
if err != nil {
|
||||||
|
return PayStub{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return payStub, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPayment returns storagenode payment data by nodeID and period.
|
||||||
|
func (service *Service) GetPayment(ctx context.Context, nodeID storj.NodeID, period string) (StoragenodePayment, error) {
|
||||||
|
payment, err := service.db.GetPayment(ctx, nodeID, period)
|
||||||
|
if err != nil {
|
||||||
|
return StoragenodePayment{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return payment, nil
|
||||||
|
}
|
@ -19,6 +19,7 @@ import (
|
|||||||
"storj.io/storj/satellite/console"
|
"storj.io/storj/satellite/console"
|
||||||
"storj.io/storj/satellite/downtime"
|
"storj.io/storj/satellite/downtime"
|
||||||
"storj.io/storj/satellite/gracefulexit"
|
"storj.io/storj/satellite/gracefulexit"
|
||||||
|
"storj.io/storj/satellite/heldamount"
|
||||||
"storj.io/storj/satellite/orders"
|
"storj.io/storj/satellite/orders"
|
||||||
"storj.io/storj/satellite/overlay"
|
"storj.io/storj/satellite/overlay"
|
||||||
"storj.io/storj/satellite/payments/stripecoinpayments"
|
"storj.io/storj/satellite/payments/stripecoinpayments"
|
||||||
@ -176,3 +177,8 @@ func (db *satelliteDB) StripeCoinPayments() stripecoinpayments.DB {
|
|||||||
func (db *satelliteDB) DowntimeTracking() downtime.DB {
|
func (db *satelliteDB) DowntimeTracking() downtime.DB {
|
||||||
return &downtimeTrackingDB{db: db}
|
return &downtimeTrackingDB{db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HeldAmount returns database for storagenode payStubs and payments info
|
||||||
|
func (db *satelliteDB) HeldAmount() heldamount.DB {
|
||||||
|
return &paymentStubs{db: db}
|
||||||
|
}
|
||||||
|
70
satellite/satellitedb/heldamount.go
Normal file
70
satellite/satellitedb/heldamount.go
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright (C) 2020 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
package satellitedb
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"storj.io/storj/pkg/storj"
|
||||||
|
"storj.io/storj/satellite/heldamount"
|
||||||
|
)
|
||||||
|
|
||||||
|
// paymentStubs is payment data for specific storagenode for some specific period by working with satellite.
|
||||||
|
//
|
||||||
|
// architecture: Database
|
||||||
|
type paymentStubs struct {
|
||||||
|
db *satelliteDB
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPaystub returns payStub by nodeID and period.
|
||||||
|
func (paystubs *paymentStubs) GetPaystub(ctx context.Context, nodeID storj.NodeID, period string) (payStub heldamount.PayStub, err error) {
|
||||||
|
query := `SELECT * FROM storagenode_paystubs WHERE node_id = $1 AND period = $2;`
|
||||||
|
|
||||||
|
row := paystubs.db.QueryRowContext(ctx, query, nodeID, period)
|
||||||
|
err = row.Scan(
|
||||||
|
&payStub.Period,
|
||||||
|
&payStub.Paid,
|
||||||
|
&payStub.Disposed,
|
||||||
|
&payStub.Owed,
|
||||||
|
&payStub.Held,
|
||||||
|
&payStub.SurgePercent,
|
||||||
|
&payStub.CompGetAudit,
|
||||||
|
&payStub.CompPutRepair,
|
||||||
|
&payStub.CompGetRepair,
|
||||||
|
&payStub.CompAtRest,
|
||||||
|
&payStub.UsageGetAudit,
|
||||||
|
&payStub.UsagePutRepair,
|
||||||
|
&payStub.UsageGetRepair,
|
||||||
|
&payStub.UsageAtRest,
|
||||||
|
&payStub.Codes,
|
||||||
|
&payStub.NodeID,
|
||||||
|
&payStub.Created,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return heldamount.PayStub{}, Error.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return payStub, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPayment returns payment by nodeID and period.
|
||||||
|
func (paystubs *paymentStubs) GetPayment(ctx context.Context, nodeID storj.NodeID, period string) (payment heldamount.StoragenodePayment, err error) {
|
||||||
|
query := `SELECT * FROM storagenode_payments WHERE node_id = $1 AND period = $2;`
|
||||||
|
|
||||||
|
row := paystubs.db.QueryRowContext(ctx, query, nodeID, period)
|
||||||
|
err = row.Scan(
|
||||||
|
&payment.ID,
|
||||||
|
&payment.Created,
|
||||||
|
&payment.NodeID,
|
||||||
|
&payment.Period,
|
||||||
|
&payment.Amount,
|
||||||
|
&payment.Receipt,
|
||||||
|
&payment.Notes,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return heldamount.StoragenodePayment{}, Error.Wrap(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return payment, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user