satellite/heldamount: payments added, endpoind for payments added
Change-Id: Ia2b9580bc353ef614680230c6f82c5bf6ded49c4
This commit is contained in:
parent
b878fcc4b2
commit
b639ec08d4
6
go.mod
6
go.mod
@ -6,7 +6,7 @@ require (
|
||||
github.com/alessio/shellescape v0.0.0-20190409004728-b115ca0f9053
|
||||
github.com/alicebob/miniredis/v2 v2.11.1
|
||||
github.com/btcsuite/btcutil v1.0.1
|
||||
github.com/calebcase/tmpfile v1.0.1
|
||||
github.com/calebcase/tmpfile v1.0.2-0.20200602150926-3af473ef8439
|
||||
github.com/cheggaaa/pb/v3 v3.0.1
|
||||
github.com/fatih/color v1.7.0
|
||||
github.com/go-redis/redis v6.14.1+incompatible
|
||||
@ -39,8 +39,8 @@ require (
|
||||
golang.org/x/sys v0.0.0-20200610111108-226ff32320da
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
|
||||
golang.org/x/tools v0.0.0-20200428211428-0c9eba77bc32 // indirect
|
||||
storj.io/common v0.0.0-20200622152042-376f8bec9266
|
||||
storj.io/drpc v0.0.12
|
||||
storj.io/common v0.0.0-20200701134427-63fe7147a3f3
|
||||
storj.io/drpc v0.0.13
|
||||
storj.io/monkit-jaeger v0.0.0-20200518165323-80778fc3f91b
|
||||
storj.io/private v0.0.0-20200605221229-3236fe879ab3
|
||||
storj.io/uplink v1.1.2-0.20200616134034-15d9aa571aa7
|
||||
|
6
go.sum
6
go.sum
@ -62,6 +62,8 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/calebcase/tmpfile v1.0.1 h1:vD8FSrbsbexhep39/6mvtbIHS3GzIRqiprDNCF6QqSk=
|
||||
github.com/calebcase/tmpfile v1.0.1/go.mod h1:iErLeG/iqJr8LaQ/gYRv4GXdqssi3jg4iSzvrA06/lw=
|
||||
github.com/calebcase/tmpfile v1.0.2-0.20200602150926-3af473ef8439 h1:fqGdSbbWVbQqNCQXd/dyZ7Bl+u8R2X7QCiNzwgyUa/M=
|
||||
github.com/calebcase/tmpfile v1.0.2-0.20200602150926-3af473ef8439/go.mod h1:iErLeG/iqJr8LaQ/gYRv4GXdqssi3jg4iSzvrA06/lw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cheggaaa/pb/v3 v3.0.1 h1:m0BngUk2LuSRYdx4fujDKNRXNDpbNCfptPfVT2m6OJY=
|
||||
@ -621,12 +623,16 @@ storj.io/common v0.0.0-20200616122322-79b46deca70e h1:eAq23qVHALvUhH1PrtHnRPUXo7
|
||||
storj.io/common v0.0.0-20200616122322-79b46deca70e/go.mod h1:ZSjZI9XJNevOP527K+PL1c68j8w5M4vbHha3V2tYWdQ=
|
||||
storj.io/common v0.0.0-20200622152042-376f8bec9266 h1:Pmvy8chvf8NsGw91nlrPq/yym1WMranq0SBLh23rhts=
|
||||
storj.io/common v0.0.0-20200622152042-376f8bec9266/go.mod h1:ZSjZI9XJNevOP527K+PL1c68j8w5M4vbHha3V2tYWdQ=
|
||||
storj.io/common v0.0.0-20200701134427-63fe7147a3f3 h1:+7dtbWpeBeFrYIesoGfhGAPxTTBThwbwmuIwbaQyFo0=
|
||||
storj.io/common v0.0.0-20200701134427-63fe7147a3f3/go.mod h1:vMAnlNbkgW6i+w/OT1h4X8w6TajOHWAT+SvFHUFCpq0=
|
||||
storj.io/drpc v0.0.11/go.mod h1:TiFc2obNjL9/3isMW1Rpxjy8V9uE0B2HMeMFGiiI7Iw=
|
||||
storj.io/drpc v0.0.11/go.mod h1:TiFc2obNjL9/3isMW1Rpxjy8V9uE0B2HMeMFGiiI7Iw=
|
||||
storj.io/drpc v0.0.12 h1:4ei1M4cnWlYxcQheX0Dg4+c12zCD+oJqfweVQVWarsA=
|
||||
storj.io/drpc v0.0.12 h1:4ei1M4cnWlYxcQheX0Dg4+c12zCD+oJqfweVQVWarsA=
|
||||
storj.io/drpc v0.0.12/go.mod h1:82nfl+6YwRwF6UG31cEWWUqv/FaKvP5SGqUvoqTxCMA=
|
||||
storj.io/drpc v0.0.12/go.mod h1:82nfl+6YwRwF6UG31cEWWUqv/FaKvP5SGqUvoqTxCMA=
|
||||
storj.io/drpc v0.0.13 h1:EDR3WiwVcIHtg+8M5vqBFmUAuJvmM2erVHIfqPPSAoc=
|
||||
storj.io/drpc v0.0.13/go.mod h1:82nfl+6YwRwF6UG31cEWWUqv/FaKvP5SGqUvoqTxCMA=
|
||||
storj.io/monkit-jaeger v0.0.0-20200518165323-80778fc3f91b h1:Bbg9JCtY6l3HrDxs3BXzT2UYnYCBLqNi6i84Y8QIPUs=
|
||||
storj.io/monkit-jaeger v0.0.0-20200518165323-80778fc3f91b/go.mod h1:gj4vuCeyCRjRmH8LIrgoyU9Dc9uR6H+/GcDUXmTbf80=
|
||||
storj.io/private v0.0.0-20200605221229-3236fe879ab3 h1:kUn1+iJmBwBTJopuNlN3daKAXLNe1u3F/cGDq0o3sak=
|
||||
|
@ -52,7 +52,7 @@ func (e *Endpoint) GetPayStub(ctx context.Context, req *pb.GetHeldAmountRequest)
|
||||
node, err := e.overlay.Get(ctx, peer.ID)
|
||||
if err != nil {
|
||||
if overlay.ErrNodeNotFound.Has(err) {
|
||||
return nil, rpcstatus.Error(rpcstatus.PermissionDenied, err.Error())
|
||||
return nil, rpcstatus.Error(rpcstatus.NotFound, err.Error())
|
||||
}
|
||||
|
||||
return nil, rpcstatus.Error(rpcstatus.Internal, err.Error())
|
||||
@ -64,7 +64,7 @@ func (e *Endpoint) GetPayStub(ctx context.Context, req *pb.GetHeldAmountRequest)
|
||||
if ErrNoDataForPeriod.Has(err) {
|
||||
return nil, rpcstatus.Error(rpcstatus.OutOfRange, err.Error())
|
||||
}
|
||||
return nil, err
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
periodTime, err := date.PeriodToTime(stub.Period)
|
||||
@ -107,7 +107,7 @@ func (e *Endpoint) GetAllPaystubs(ctx context.Context, req *pb.GetAllPaystubsReq
|
||||
node, err := e.overlay.Get(ctx, peer.ID)
|
||||
if err != nil {
|
||||
if overlay.ErrNodeNotFound.Has(err) {
|
||||
return nil, rpcstatus.Error(rpcstatus.PermissionDenied, err.Error())
|
||||
return nil, rpcstatus.Error(rpcstatus.NotFound, err.Error())
|
||||
}
|
||||
|
||||
return nil, rpcstatus.Error(rpcstatus.Internal, err.Error())
|
||||
@ -118,7 +118,7 @@ func (e *Endpoint) GetAllPaystubs(ctx context.Context, req *pb.GetAllPaystubsReq
|
||||
if ErrNoDataForPeriod.Has(err) {
|
||||
return nil, rpcstatus.Error(rpcstatus.OutOfRange, err.Error())
|
||||
}
|
||||
return nil, err
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
var paystubs []*pb.GetHeldAmountResponse
|
||||
@ -130,7 +130,7 @@ func (e *Endpoint) GetAllPaystubs(ctx context.Context, req *pb.GetAllPaystubsReq
|
||||
for i := 0; i < len(stubs); i++ {
|
||||
period, err := date.PeriodToTime(stubs[i].Period)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
heldAmountResponse := pb.GetHeldAmountResponse{
|
||||
@ -162,3 +162,97 @@ func (e *Endpoint) GetAllPaystubs(ctx context.Context, req *pb.GetAllPaystubsReq
|
||||
|
||||
return &response, 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.NotFound, err.Error())
|
||||
}
|
||||
|
||||
return nil, rpcstatus.Error(rpcstatus.Internal, err.Error())
|
||||
}
|
||||
|
||||
payment, err := e.service.GetPayment(ctx, node.Id, req.Period.String())
|
||||
if err != nil {
|
||||
if ErrNoDataForPeriod.Has(err) {
|
||||
return nil, rpcstatus.Error(rpcstatus.OutOfRange, err.Error())
|
||||
}
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
timePeriod, err := date.PeriodToTime(payment.Period)
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return &pb.GetPaymentResponse{
|
||||
NodeId: payment.NodeID,
|
||||
CreatedAt: payment.Created,
|
||||
Period: timePeriod,
|
||||
Amount: payment.Amount,
|
||||
Receipt: payment.Receipt,
|
||||
Notes: payment.Notes,
|
||||
Id: payment.ID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetAllPayments sends all payments to node.
|
||||
func (e *Endpoint) GetAllPayments(ctx context.Context, req *pb.GetAllPaymentsRequest) (_ *pb.GetAllPaymentsResponse, 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.NotFound, err.Error())
|
||||
}
|
||||
|
||||
return nil, rpcstatus.Error(rpcstatus.Internal, err.Error())
|
||||
}
|
||||
|
||||
allPayments, err := e.service.GetAllPayments(ctx, node.Id)
|
||||
if err != nil {
|
||||
if ErrNoDataForPeriod.Has(err) {
|
||||
return nil, rpcstatus.Error(rpcstatus.OutOfRange, err.Error())
|
||||
}
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
var payments []*pb.GetPaymentResponse
|
||||
|
||||
response := pb.GetAllPaymentsResponse{
|
||||
Payment: payments,
|
||||
}
|
||||
|
||||
for i := 0; i < len(allPayments); i++ {
|
||||
period, err := date.PeriodToTime(allPayments[i].Period)
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
paymentResponse := pb.GetPaymentResponse{
|
||||
NodeId: allPayments[i].NodeID,
|
||||
CreatedAt: allPayments[i].Created,
|
||||
Period: period,
|
||||
Amount: allPayments[i].Amount,
|
||||
Receipt: allPayments[i].Receipt,
|
||||
Notes: allPayments[i].Notes,
|
||||
Id: allPayments[i].ID,
|
||||
}
|
||||
|
||||
response.Payment = append(response.Payment, &paymentResponse)
|
||||
}
|
||||
|
||||
return &response, nil
|
||||
}
|
||||
|
@ -23,11 +23,20 @@ type DB interface {
|
||||
GetAllPaystubs(ctx context.Context, nodeID storj.NodeID) ([]PayStub, error)
|
||||
// CreatePaystub insert paystub into db.
|
||||
CreatePaystub(ctx context.Context, stub PayStub) (err error)
|
||||
// GetPayment return storagenode payment by nodeID and period.
|
||||
GetPayment(ctx context.Context, nodeID storj.NodeID, period string) (StoragenodePayment, error)
|
||||
// CreatePayment insert payment into db.
|
||||
CreatePayment(ctx context.Context, payment StoragenodePayment) (err error)
|
||||
// GetAllPayments return all payments by nodeID.
|
||||
GetAllPayments(ctx context.Context, nodeID storj.NodeID) ([]StoragenodePayment, error)
|
||||
}
|
||||
|
||||
// ErrNoDataForPeriod represents errors from the heldamount database.
|
||||
var ErrNoDataForPeriod = errs.Class("no payStub/payments for period error")
|
||||
|
||||
// Error is the default error class for heldamount package.
|
||||
var Error = errs.Class("heldamount")
|
||||
|
||||
// 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"`
|
||||
@ -53,6 +62,17 @@ type PayStub struct {
|
||||
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 string `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
|
||||
@ -73,7 +93,7 @@ func NewService(log *zap.Logger, db DB) *Service {
|
||||
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{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return payStub, nil
|
||||
@ -83,8 +103,28 @@ func (service *Service) GetPayStub(ctx context.Context, nodeID storj.NodeID, per
|
||||
func (service *Service) GetAllPaystubs(ctx context.Context, nodeID storj.NodeID) ([]PayStub, error) {
|
||||
payStubs, err := service.db.GetAllPaystubs(ctx, nodeID)
|
||||
if err != nil {
|
||||
return []PayStub{}, err
|
||||
return []PayStub{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return payStubs, 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{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return payment, nil
|
||||
}
|
||||
|
||||
// GetAllPayments returns all payments by nodeID.
|
||||
func (service *Service) GetAllPayments(ctx context.Context, nodeID storj.NodeID) ([]StoragenodePayment, error) {
|
||||
payments, err := service.db.GetAllPayments(ctx, nodeID)
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return payments, nil
|
||||
}
|
||||
|
@ -205,5 +205,36 @@ func TestHeldAmountDB(t *testing.T) {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
payment := heldamount.StoragenodePayment{
|
||||
ID: 1,
|
||||
Created: time.Now().UTC(),
|
||||
NodeID: NodeID,
|
||||
Period: "2020-01",
|
||||
Amount: 123,
|
||||
Receipt: "receipt",
|
||||
Notes: "notes",
|
||||
}
|
||||
|
||||
t.Run("Test StorePayment", func(t *testing.T) {
|
||||
err := heldAmount.CreatePayment(ctx, payment)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Test GetPayment", func(t *testing.T) {
|
||||
paym, err := heldAmount.GetPayment(ctx, NodeID, period)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, paym.NodeID, payment.NodeID)
|
||||
assert.Equal(t, paym.Period, payment.Period)
|
||||
assert.Equal(t, paym.Amount, payment.Amount)
|
||||
assert.Equal(t, paym.Notes, payment.Notes)
|
||||
assert.Equal(t, paym.Receipt, payment.Receipt)
|
||||
|
||||
paym, err = heldAmount.GetPayment(ctx, NodeID, "")
|
||||
assert.Error(t, err)
|
||||
|
||||
paym, err = heldAmount.GetPayment(ctx, storj.NodeID{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, period)
|
||||
assert.Error(t, err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -135,3 +135,78 @@ func (paystubs *paymentStubs) CreatePaystub(ctx context.Context, stub heldamount
|
||||
dbx.StoragenodePaystub_Paid(stub.Paid),
|
||||
)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
if sql.ErrNoRows == err {
|
||||
return heldamount.StoragenodePayment{}, heldamount.ErrNoDataForPeriod.Wrap(err)
|
||||
}
|
||||
|
||||
return heldamount.StoragenodePayment{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return payment, nil
|
||||
}
|
||||
|
||||
// CreatePayment inserts storagenode_payment into database.
|
||||
func (paystubs *paymentStubs) CreatePayment(ctx context.Context, payment heldamount.StoragenodePayment) (err error) {
|
||||
return paystubs.db.CreateNoReturn_StoragenodePayment(
|
||||
ctx,
|
||||
dbx.StoragenodePayment_NodeId(payment.NodeID[:]),
|
||||
dbx.StoragenodePayment_Period(payment.Period),
|
||||
dbx.StoragenodePayment_Amount(payment.Amount),
|
||||
dbx.StoragenodePayment_Create_Fields{
|
||||
Receipt: dbx.StoragenodePayment_Receipt(payment.Receipt),
|
||||
Notes: dbx.StoragenodePayment_Notes(payment.Notes),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// GetAllPayments return all payments by nodeID.
|
||||
func (paystubs *paymentStubs) GetAllPayments(ctx context.Context, nodeID storj.NodeID) (payments []heldamount.StoragenodePayment, err error) {
|
||||
query := `SELECT * FROM storagenode_payments WHERE node_id = $1;`
|
||||
|
||||
rows, err := paystubs.db.QueryContext(ctx, query, nodeID)
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err = errs.Combine(err, Error.Wrap(rows.Close()))
|
||||
}()
|
||||
|
||||
for rows.Next() {
|
||||
payment := heldamount.StoragenodePayment{}
|
||||
|
||||
err = rows.Scan(
|
||||
&payment.ID,
|
||||
&payment.Created,
|
||||
&payment.NodeID,
|
||||
&payment.Period,
|
||||
&payment.Amount,
|
||||
&payment.Receipt,
|
||||
&payment.Notes,
|
||||
)
|
||||
|
||||
if err = rows.Err(); err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
payments = append(payments, payment)
|
||||
}
|
||||
|
||||
return payments, Error.Wrap(rows.Err())
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user