2021-02-04 15:44:31 +00:00
|
|
|
// Copyright (C) 2021 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package multinode_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
2021-05-05 18:10:58 +01:00
|
|
|
"time"
|
2021-02-04 15:44:31 +00:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"go.uber.org/zap/zaptest"
|
|
|
|
|
2021-05-05 18:10:58 +01:00
|
|
|
"storj.io/common/pb"
|
|
|
|
"storj.io/common/rpc"
|
|
|
|
"storj.io/common/storj"
|
2021-02-04 15:44:31 +00:00
|
|
|
"storj.io/common/testcontext"
|
|
|
|
"storj.io/common/testrand"
|
|
|
|
"storj.io/storj/private/multinodepb"
|
2021-05-05 18:10:58 +01:00
|
|
|
"storj.io/storj/storagenode"
|
2021-02-04 15:44:31 +00:00
|
|
|
"storj.io/storj/storagenode/apikeys"
|
|
|
|
"storj.io/storj/storagenode/multinode"
|
|
|
|
"storj.io/storj/storagenode/payouts"
|
2021-05-05 18:10:58 +01:00
|
|
|
"storj.io/storj/storagenode/payouts/estimatedpayouts"
|
|
|
|
"storj.io/storj/storagenode/pricing"
|
|
|
|
"storj.io/storj/storagenode/reputation"
|
|
|
|
"storj.io/storj/storagenode/storagenodedb/storagenodedbtest"
|
|
|
|
"storj.io/storj/storagenode/trust"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
actions = []pb.PieceAction{
|
|
|
|
pb.PieceAction_INVALID,
|
|
|
|
|
|
|
|
pb.PieceAction_PUT,
|
|
|
|
pb.PieceAction_GET,
|
|
|
|
pb.PieceAction_GET_AUDIT,
|
|
|
|
pb.PieceAction_GET_REPAIR,
|
|
|
|
pb.PieceAction_PUT_REPAIR,
|
|
|
|
pb.PieceAction_DELETE,
|
|
|
|
|
|
|
|
pb.PieceAction_PUT,
|
|
|
|
pb.PieceAction_GET,
|
|
|
|
pb.PieceAction_GET_AUDIT,
|
|
|
|
pb.PieceAction_GET_REPAIR,
|
|
|
|
pb.PieceAction_PUT_REPAIR,
|
|
|
|
pb.PieceAction_DELETE,
|
|
|
|
}
|
2021-02-04 15:44:31 +00:00
|
|
|
)
|
|
|
|
|
2021-05-05 21:01:16 +01:00
|
|
|
func TestPayoutsEndpointSummary(t *testing.T) {
|
|
|
|
storagenodedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db storagenode.DB) {
|
2021-02-04 15:44:31 +00:00
|
|
|
log := zaptest.NewLogger(t)
|
2021-05-05 21:01:16 +01:00
|
|
|
satelliteID := testrand.NodeID()
|
|
|
|
apikeydb := db.APIKeys()
|
|
|
|
payoutdb := db.Payout()
|
|
|
|
service := apikeys.NewService(apikeydb)
|
|
|
|
|
|
|
|
// Initialize a trust pool
|
|
|
|
poolConfig := trust.Config{
|
|
|
|
CachePath: ctx.File("trust-cache.json"),
|
|
|
|
}
|
|
|
|
poolConfig.Sources = append(poolConfig.Sources, &trust.StaticURLSource{URL: trust.SatelliteURL{ID: satelliteID}})
|
|
|
|
|
2021-07-08 10:14:15 +01:00
|
|
|
trustPool, err := trust.NewPool(zaptest.NewLogger(t), trust.Dialer(rpc.Dialer{}), poolConfig, db.Satellites())
|
2021-05-05 21:01:16 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, trustPool.Refresh(ctx))
|
|
|
|
|
2021-07-29 15:30:57 +01:00
|
|
|
payoutsService, err := payouts.NewService(log, db.Payout(), db.Reputation(), db.Satellites(), nil)
|
2021-04-22 19:50:42 +01:00
|
|
|
require.NoError(t, err)
|
2021-05-05 21:01:16 +01:00
|
|
|
estimatedPayoutsService := estimatedpayouts.NewService(db.Bandwidth(), db.Reputation(), db.StorageUsage(), db.Pricing(), db.Satellites(), trustPool)
|
2021-04-22 19:50:42 +01:00
|
|
|
endpoint := multinode.NewPayoutEndpoint(log, service, db.Payout(), estimatedPayoutsService, payoutsService)
|
2021-02-04 15:44:31 +00:00
|
|
|
|
2021-05-05 18:34:10 +01:00
|
|
|
id := testrand.NodeID()
|
|
|
|
id2 := testrand.NodeID()
|
|
|
|
|
2021-02-04 15:44:31 +00:00
|
|
|
var amount int64 = 200
|
2021-05-05 18:34:10 +01:00
|
|
|
var amount2 int64 = 150
|
2021-02-04 15:44:31 +00:00
|
|
|
|
2021-05-05 21:01:16 +01:00
|
|
|
err = payoutdb.StorePayStub(ctx, payouts.PayStub{
|
2021-05-05 18:34:10 +01:00
|
|
|
SatelliteID: id,
|
|
|
|
Held: amount,
|
|
|
|
Paid: amount,
|
2021-05-14 23:03:38 +01:00
|
|
|
CompAtRest: amount,
|
2021-05-05 18:34:10 +01:00
|
|
|
Period: "2020-10",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2021-05-05 21:01:16 +01:00
|
|
|
err = payoutdb.StorePayStub(ctx, payouts.PayStub{
|
2021-05-05 18:34:10 +01:00
|
|
|
SatelliteID: id2,
|
|
|
|
Held: amount2,
|
|
|
|
Paid: amount2,
|
|
|
|
Period: "2020-11",
|
2021-02-04 15:44:31 +00:00
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
key, err := service.Issue(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2021-05-25 17:48:45 +01:00
|
|
|
response, err := endpoint.SummaryPeriod(ctx, &multinodepb.SummaryPeriodRequest{
|
2021-05-05 18:34:10 +01:00
|
|
|
Header: &multinodepb.RequestHeader{
|
|
|
|
ApiKey: key.Secret[:],
|
|
|
|
}, Period: "2020-10",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, response.PayoutInfo.Paid, amount)
|
|
|
|
require.Equal(t, response.PayoutInfo.Held, amount)
|
|
|
|
|
2021-05-25 17:48:45 +01:00
|
|
|
response2, err := endpoint.Summary(ctx, &multinodepb.SummaryRequest{
|
2021-02-04 15:44:31 +00:00
|
|
|
Header: &multinodepb.RequestHeader{
|
|
|
|
ApiKey: key.Secret[:],
|
|
|
|
},
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
2021-05-05 18:34:10 +01:00
|
|
|
require.Equal(t, response2.PayoutInfo.Paid, amount+amount2)
|
|
|
|
require.Equal(t, response2.PayoutInfo.Held, amount+amount2)
|
2021-05-05 21:01:16 +01:00
|
|
|
|
2021-05-25 17:48:45 +01:00
|
|
|
response3, err := endpoint.SummarySatellitePeriod(ctx, &multinodepb.SummarySatellitePeriodRequest{
|
2021-05-05 21:01:16 +01:00
|
|
|
Header: &multinodepb.RequestHeader{
|
|
|
|
ApiKey: key.Secret[:],
|
|
|
|
}, SatelliteId: id2, Period: "2020-11",
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, response3.PayoutInfo.Paid, amount2)
|
|
|
|
require.Equal(t, response3.PayoutInfo.Held, amount2)
|
|
|
|
|
2021-05-25 17:48:45 +01:00
|
|
|
response4, err := endpoint.SummarySatellite(ctx, &multinodepb.SummarySatelliteRequest{
|
2021-05-05 21:01:16 +01:00
|
|
|
Header: &multinodepb.RequestHeader{
|
|
|
|
ApiKey: key.Secret[:],
|
|
|
|
}, SatelliteId: id,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, response4.PayoutInfo.Paid, amount)
|
|
|
|
require.Equal(t, response4.PayoutInfo.Held, amount)
|
2021-02-04 15:44:31 +00:00
|
|
|
})
|
|
|
|
}
|
2021-05-05 18:10:58 +01:00
|
|
|
|
2021-05-05 21:01:16 +01:00
|
|
|
func TestPayoutsEndpointEstimations(t *testing.T) {
|
2021-05-05 18:10:58 +01:00
|
|
|
storagenodedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db storagenode.DB) {
|
|
|
|
satelliteID := testrand.NodeID()
|
|
|
|
bandwidthdb := db.Bandwidth()
|
|
|
|
pricingdb := db.Pricing()
|
|
|
|
storageusagedb := db.StorageUsage()
|
|
|
|
reputationdb := db.Reputation()
|
|
|
|
|
|
|
|
log := zaptest.NewLogger(t)
|
|
|
|
service := apikeys.NewService(db.APIKeys())
|
|
|
|
|
|
|
|
key, err := service.Issue(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// Initialize a trust pool
|
|
|
|
poolConfig := trust.Config{
|
|
|
|
CachePath: ctx.File("trust-cache.json"),
|
|
|
|
}
|
|
|
|
poolConfig.Sources = append(poolConfig.Sources, &trust.StaticURLSource{URL: trust.SatelliteURL{ID: satelliteID}})
|
|
|
|
|
2021-07-08 10:14:15 +01:00
|
|
|
trustPool, err := trust.NewPool(zaptest.NewLogger(t), trust.Dialer(rpc.Dialer{}), poolConfig, db.Satellites())
|
2021-05-05 18:10:58 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, trustPool.Refresh(ctx))
|
|
|
|
|
2021-07-29 15:30:57 +01:00
|
|
|
payoutsService, err := payouts.NewService(log, db.Payout(), db.Reputation(), db.Satellites(), nil)
|
2021-04-22 19:50:42 +01:00
|
|
|
require.NoError(t, err)
|
2021-05-05 18:10:58 +01:00
|
|
|
estimatedPayoutsService := estimatedpayouts.NewService(db.Bandwidth(), db.Reputation(), db.StorageUsage(), db.Pricing(), db.Satellites(), trustPool)
|
2021-04-22 19:50:42 +01:00
|
|
|
endpoint := multinode.NewPayoutEndpoint(log, service, db.Payout(), estimatedPayoutsService, payoutsService)
|
2021-05-05 18:10:58 +01:00
|
|
|
|
|
|
|
now := time.Now().UTC().Add(-2 * time.Hour)
|
|
|
|
|
|
|
|
for _, action := range actions {
|
|
|
|
err := bandwidthdb.Add(ctx, satelliteID, action, 2300000000000, now)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
|
|
|
var satellites []storj.NodeID
|
|
|
|
|
|
|
|
satellites = append(satellites, satelliteID)
|
2022-10-10 12:35:58 +01:00
|
|
|
stamps := storagenodedbtest.MakeStorageUsageStamps(satellites, 30, time.Now().UTC())
|
2021-05-05 18:10:58 +01:00
|
|
|
|
|
|
|
err = storageusagedb.Store(ctx, stamps)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
err = reputationdb.Store(ctx, reputation.Stats{
|
|
|
|
SatelliteID: satelliteID,
|
|
|
|
JoinedAt: now.AddDate(0, -2, 0),
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
egressPrice, repairPrice, auditPrice, diskPrice := int64(2000), int64(1000), int64(1000), int64(150)
|
|
|
|
|
|
|
|
err = pricingdb.Store(ctx, pricing.Pricing{
|
|
|
|
SatelliteID: satelliteID,
|
|
|
|
EgressBandwidth: egressPrice,
|
|
|
|
RepairBandwidth: repairPrice,
|
|
|
|
AuditBandwidth: auditPrice,
|
|
|
|
DiskSpace: diskPrice,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-07-01 10:32:17 +01:00
|
|
|
t.Run("EstimatedPayoutTotal", func(t *testing.T) {
|
2021-05-05 18:10:58 +01:00
|
|
|
estimation, err := estimatedPayoutsService.GetAllSatellitesEstimatedPayout(ctx, time.Now())
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2021-05-25 17:48:45 +01:00
|
|
|
resp, err := endpoint.EstimatedPayout(ctx, &multinodepb.EstimatedPayoutRequest{Header: &multinodepb.RequestHeader{
|
2021-05-05 18:10:58 +01:00
|
|
|
ApiKey: key.Secret[:],
|
|
|
|
}})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
require.EqualValues(t, estimation.CurrentMonthExpectations, resp.EstimatedEarnings)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2021-05-14 23:03:38 +01:00
|
|
|
func TestPayoutsUndistributedEndpoint(t *testing.T) {
|
|
|
|
storagenodedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db storagenode.DB) {
|
|
|
|
payoutdb := db.Payout()
|
|
|
|
satelliteID := testrand.NodeID()
|
|
|
|
|
|
|
|
log := zaptest.NewLogger(t)
|
|
|
|
service := apikeys.NewService(db.APIKeys())
|
|
|
|
|
|
|
|
key, err := service.Issue(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
// Initialize a trust pool
|
|
|
|
poolConfig := trust.Config{
|
|
|
|
CachePath: ctx.File("trust-cache.json"),
|
|
|
|
}
|
|
|
|
poolConfig.Sources = append(poolConfig.Sources, &trust.StaticURLSource{URL: trust.SatelliteURL{ID: satelliteID}})
|
|
|
|
|
2021-07-08 10:14:15 +01:00
|
|
|
trustPool, err := trust.NewPool(zaptest.NewLogger(t), trust.Dialer(rpc.Dialer{}), poolConfig, db.Satellites())
|
2021-05-14 23:03:38 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.NoError(t, trustPool.Refresh(ctx))
|
|
|
|
|
2021-07-29 15:30:57 +01:00
|
|
|
payoutsService, err := payouts.NewService(log, db.Payout(), db.Reputation(), db.Satellites(), nil)
|
2021-04-22 19:50:42 +01:00
|
|
|
require.NoError(t, err)
|
2021-05-14 23:03:38 +01:00
|
|
|
estimatedPayoutsService := estimatedpayouts.NewService(db.Bandwidth(), db.Reputation(), db.StorageUsage(), db.Pricing(), db.Satellites(), trustPool)
|
2021-04-22 19:50:42 +01:00
|
|
|
endpoint := multinode.NewPayoutEndpoint(log, service, db.Payout(), estimatedPayoutsService, payoutsService)
|
|
|
|
|
2021-05-14 23:03:38 +01:00
|
|
|
satelliteID1 := testrand.NodeID()
|
|
|
|
satelliteID2 := testrand.NodeID()
|
|
|
|
|
|
|
|
err = payoutdb.StorePayStub(ctx, payouts.PayStub{
|
|
|
|
SatelliteID: satelliteID2,
|
|
|
|
Period: "2020-01",
|
|
|
|
Distributed: 150,
|
|
|
|
Paid: 250,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
err = payoutdb.StorePayStub(ctx, payouts.PayStub{
|
|
|
|
SatelliteID: satelliteID2,
|
|
|
|
Period: "2020-02",
|
|
|
|
Distributed: 250,
|
|
|
|
Paid: 350,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
err = payoutdb.StorePayStub(ctx, payouts.PayStub{
|
|
|
|
SatelliteID: satelliteID1,
|
|
|
|
Period: "2020-01",
|
|
|
|
Distributed: 100,
|
|
|
|
Paid: 300,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
err = payoutdb.StorePayStub(ctx, payouts.PayStub{
|
|
|
|
SatelliteID: satelliteID1,
|
|
|
|
Period: "2020-02",
|
|
|
|
Distributed: 400,
|
|
|
|
Paid: 500,
|
|
|
|
})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
resp, err := endpoint.Undistributed(ctx, &multinodepb.UndistributedRequest{Header: &multinodepb.RequestHeader{
|
|
|
|
ApiKey: key.Secret[:],
|
|
|
|
}})
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
require.EqualValues(t, 500, resp.Total)
|
|
|
|
})
|
|
|
|
}
|