mnd/payouts: estimations replaced with expectations
Added expectations endpoint (estimations and distributed), added coalesce to db query, so in case of empty payouts db 0 will be returned instead of error. Change-Id: I535f14ef097876448d8949bc302895b25da2b6e7
This commit is contained in:
parent
83e82eb473
commit
79172777bd
@ -53,8 +53,8 @@ func (controller *Payouts) GetAllNodesTotalEarned(w http.ResponseWriter, r *http
|
||||
}
|
||||
}
|
||||
|
||||
// NodeEstimations handles node's estimated.
|
||||
func (controller *Payouts) NodeEstimations(w http.ResponseWriter, r *http.Request) {
|
||||
// NodeExpectations handles node's estimated and undistributed.
|
||||
func (controller *Payouts) NodeExpectations(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var err error
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
@ -74,33 +74,33 @@ func (controller *Payouts) NodeEstimations(w http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
estimations, err := controller.service.NodeEstimations(ctx, nodeID)
|
||||
expectations, err := controller.service.NodeExpectations(ctx, nodeID)
|
||||
if err != nil {
|
||||
controller.serveError(w, http.StatusInternalServerError, ErrPayouts.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.NewEncoder(w).Encode(estimations); err != nil {
|
||||
if err = json.NewEncoder(w).Encode(expectations); err != nil {
|
||||
controller.log.Error("failed to write json response", zap.Error(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Estimations handles nodes estimated earnings.
|
||||
func (controller *Payouts) Estimations(w http.ResponseWriter, r *http.Request) {
|
||||
// Expectations handles nodes estimated and undistributed earnings.
|
||||
func (controller *Payouts) Expectations(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var err error
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
|
||||
estimations, err := controller.service.Estimations(ctx)
|
||||
expectations, err := controller.service.Expectations(ctx)
|
||||
if err != nil {
|
||||
controller.serveError(w, http.StatusInternalServerError, ErrPayouts.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.NewEncoder(w).Encode(estimations); err != nil {
|
||||
if err = json.NewEncoder(w).Encode(expectations); err != nil {
|
||||
controller.log.Error("failed to write json response", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
@ -80,8 +80,8 @@ func NewServer(log *zap.Logger, config Config, nodes *nodes.Service, payouts *pa
|
||||
payoutsRouter.HandleFunc("/summary/{period}", payoutsController.PeriodSummary).Methods(http.MethodGet)
|
||||
payoutsRouter.HandleFunc("/summary", payoutsController.Summary).Methods(http.MethodGet)
|
||||
payoutsRouter.HandleFunc("/total-earned", payoutsController.GetAllNodesTotalEarned).Methods(http.MethodGet)
|
||||
payoutsRouter.HandleFunc("/estimations/{nodeID}", payoutsController.NodeEstimations).Methods(http.MethodGet)
|
||||
payoutsRouter.HandleFunc("/estimations", payoutsController.Estimations).Methods(http.MethodGet)
|
||||
payoutsRouter.HandleFunc("/expectations/{nodeID}", payoutsController.NodeExpectations).Methods(http.MethodGet)
|
||||
payoutsRouter.HandleFunc("/expectations", payoutsController.Expectations).Methods(http.MethodGet)
|
||||
|
||||
if server.config.StaticDir != "" {
|
||||
router.PathPrefix("/static/").Handler(http.StripPrefix("/static", fs))
|
||||
|
@ -41,3 +41,9 @@ func (summary *Summary) Add(held, paid int64, id storj.NodeID, name string) {
|
||||
NodeName: name,
|
||||
})
|
||||
}
|
||||
|
||||
// Expectations contains estimated and undistributed payouts.
|
||||
type Expectations struct {
|
||||
CurrentMonthEstimation int64 `json:"currentMonthEstimation"`
|
||||
Undistributed int64 `json:"undistributed"`
|
||||
}
|
||||
|
@ -308,54 +308,55 @@ func (service *Service) getAllSatellitesAllTime(ctx context.Context, node nodes.
|
||||
return response.PayoutInfo, nil
|
||||
}
|
||||
|
||||
// NodeEstimations returns node's estimated earnings.
|
||||
func (service *Service) NodeEstimations(ctx context.Context, nodeID storj.NodeID) (_ int64, err error) {
|
||||
// NodeExpectations returns node's estimated and undistributed earnings.
|
||||
func (service *Service) NodeExpectations(ctx context.Context, nodeID storj.NodeID) (_ Expectations, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
node, err := service.nodes.Get(ctx, nodeID)
|
||||
if err != nil {
|
||||
return 0, Error.Wrap(err)
|
||||
return Expectations{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
est, err := service.nodeEstimations(ctx, node)
|
||||
expectation, err := service.nodeExpectations(ctx, node)
|
||||
if err != nil {
|
||||
return 0, Error.Wrap(err)
|
||||
return Expectations{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return est, nil
|
||||
return expectation, nil
|
||||
}
|
||||
|
||||
// Estimations returns all nodes estimated earnings.
|
||||
func (service *Service) Estimations(ctx context.Context) (_ int64, err error) {
|
||||
// Expectations returns all nodes estimated and undistributed earnings.
|
||||
func (service *Service) Expectations(ctx context.Context) (_ Expectations, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
var estimations int64
|
||||
var expectations Expectations
|
||||
|
||||
list, err := service.nodes.List(ctx)
|
||||
if err != nil {
|
||||
return 0, Error.Wrap(err)
|
||||
return Expectations{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
for _, node := range list {
|
||||
est, err := service.nodeEstimations(ctx, node)
|
||||
expectation, err := service.nodeExpectations(ctx, node)
|
||||
if err != nil {
|
||||
return 0, Error.Wrap(err)
|
||||
return Expectations{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
estimations += est
|
||||
expectations.Undistributed += expectation.Undistributed
|
||||
expectations.CurrentMonthEstimation += expectation.CurrentMonthEstimation
|
||||
}
|
||||
|
||||
return estimations, nil
|
||||
return expectations, nil
|
||||
}
|
||||
|
||||
// nodeEstimations retrieves data from a single node.
|
||||
func (service *Service) nodeEstimations(ctx context.Context, node nodes.Node) (_ int64, err error) {
|
||||
// nodeExpectations retrieves data from a single node.
|
||||
func (service *Service) nodeExpectations(ctx context.Context, node nodes.Node) (_ Expectations, err error) {
|
||||
conn, err := service.dialer.DialNodeURL(ctx, storj.NodeURL{
|
||||
ID: node.ID,
|
||||
Address: node.PublicAddress,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, Error.Wrap(err)
|
||||
return Expectations{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
@ -369,10 +370,15 @@ func (service *Service) nodeEstimations(ctx context.Context, node nodes.Node) (_
|
||||
|
||||
estimated, err := payoutClient.EstimatedPayoutTotal(ctx, &multinodepb.EstimatedPayoutTotalRequest{Header: header})
|
||||
if err != nil {
|
||||
return 0, Error.Wrap(err)
|
||||
return Expectations{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return estimated.EstimatedEarnings, nil
|
||||
undistributed, err := payoutClient.Undistributed(ctx, &multinodepb.UndistributedRequest{Header: header})
|
||||
if err != nil {
|
||||
return Expectations{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return Expectations{Undistributed: undistributed.Total, CurrentMonthEstimation: estimated.EstimatedEarnings}, nil
|
||||
}
|
||||
|
||||
// getAmount returns earned from node.
|
||||
|
@ -456,12 +456,19 @@ func TestPayouts(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestPayoutsUndistributedEndpoint(t *testing.T) {
|
||||
func TestUndistributed(t *testing.T) {
|
||||
storagenodedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db storagenode.DB) {
|
||||
payoutdb := db.Payout()
|
||||
satelliteID1 := testrand.NodeID()
|
||||
satelliteID2 := testrand.NodeID()
|
||||
|
||||
t.Run("empty db no error", func(t *testing.T) {
|
||||
undistributed, err := payoutdb.GetUndistributed(ctx)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, undistributed, 0)
|
||||
})
|
||||
|
||||
t.Run("few paystubs with different satellites", func(t *testing.T) {
|
||||
err := payoutdb.StorePayStub(ctx, payouts.PayStub{
|
||||
SatelliteID: satelliteID2,
|
||||
Period: "2020-01",
|
||||
@ -498,4 +505,5 @@ func TestPayoutsUndistributedEndpoint(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, undistributed, 500)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -572,13 +572,14 @@ func (db *payoutDB) GetUndistributed(ctx context.Context) (_ int64, err error) {
|
||||
var distributed, paid int64
|
||||
|
||||
rowPayment := db.QueryRowContext(ctx,
|
||||
`SELECT SUM(distributed), SUM(paid) FROM paystubs`)
|
||||
`SELECT COALESCE(SUM(distributed),0), COALESCE(SUM(paid), 0) FROM paystubs`)
|
||||
|
||||
err = rowPayment.Scan(&distributed, &paid)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return 0, payouts.ErrNoPayStubForPeriod.Wrap(err)
|
||||
}
|
||||
|
||||
return 0, ErrPayout.Wrap(err)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user