2020-03-16 04:28:03 +00:00
|
|
|
// Copyright (C) 2020 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
2021-04-22 19:50:42 +01:00
|
|
|
package payouts_test
|
2020-03-16 04:28:03 +00:00
|
|
|
|
|
|
|
import (
|
2021-07-29 15:30:57 +01:00
|
|
|
"context"
|
|
|
|
"errors"
|
|
|
|
"sync"
|
2020-03-16 04:28:03 +00:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
2021-04-22 19:50:42 +01:00
|
|
|
"go.uber.org/zap/zaptest"
|
|
|
|
|
2021-07-29 15:30:57 +01:00
|
|
|
"storj.io/common/identity"
|
|
|
|
"storj.io/common/storj"
|
2021-04-22 19:50:42 +01:00
|
|
|
"storj.io/common/testcontext"
|
|
|
|
"storj.io/common/testrand"
|
|
|
|
"storj.io/storj/storagenode"
|
|
|
|
"storj.io/storj/storagenode/payouts"
|
|
|
|
"storj.io/storj/storagenode/storagenodedb/storagenodedbtest"
|
2021-07-29 15:30:57 +01:00
|
|
|
"storj.io/storj/storagenode/trust"
|
2020-03-16 04:28:03 +00:00
|
|
|
)
|
|
|
|
|
2021-04-22 19:50:42 +01:00
|
|
|
func TestServiceHeldAmountHistory(t *testing.T) {
|
|
|
|
storagenodedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db storagenode.DB) {
|
|
|
|
log := zaptest.NewLogger(t)
|
|
|
|
payoutsDB := db.Payout()
|
2021-07-08 10:14:15 +01:00
|
|
|
satellitesDB := db.Satellites()
|
2021-07-29 15:30:57 +01:00
|
|
|
source := &fakeSource{}
|
|
|
|
pool, err := trust.NewPool(log, newFakeIdentityResolver(), trust.Config{
|
|
|
|
Sources: []trust.Source{source},
|
|
|
|
CachePath: ctx.File("trust-cache.json"),
|
|
|
|
}, satellitesDB)
|
|
|
|
require.NoError(t, err)
|
2021-04-22 19:50:42 +01:00
|
|
|
|
|
|
|
satelliteID1 := testrand.NodeID()
|
|
|
|
satelliteID2 := testrand.NodeID()
|
|
|
|
satelliteID3 := testrand.NodeID()
|
|
|
|
|
2021-07-29 15:30:57 +01:00
|
|
|
// populate pool
|
|
|
|
source.entries = []trust.Entry{
|
|
|
|
{
|
|
|
|
SatelliteURL: trust.SatelliteURL{
|
|
|
|
ID: satelliteID1,
|
|
|
|
Host: "foo.test",
|
|
|
|
Port: 7777,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
SatelliteURL: trust.SatelliteURL{
|
|
|
|
ID: satelliteID2,
|
|
|
|
Host: "bar.test",
|
|
|
|
Port: 7777,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
SatelliteURL: trust.SatelliteURL{
|
|
|
|
ID: satelliteID3,
|
|
|
|
Host: "baz.test",
|
|
|
|
Port: 7777,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
require.NoError(t, pool.Refresh(context.Background()))
|
2021-04-22 19:50:42 +01:00
|
|
|
|
|
|
|
// add paystubs
|
|
|
|
paystubs := []payouts.PayStub{
|
|
|
|
{
|
|
|
|
SatelliteID: satelliteID1,
|
|
|
|
Period: "2021-01",
|
|
|
|
Held: 10,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
SatelliteID: satelliteID1,
|
|
|
|
Period: "2021-02",
|
|
|
|
Held: 10,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
SatelliteID: satelliteID2,
|
|
|
|
Period: "2021-01",
|
|
|
|
Held: 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
SatelliteID: satelliteID2,
|
|
|
|
Period: "2021-02",
|
|
|
|
Held: 0,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, paystub := range paystubs {
|
|
|
|
err = payoutsDB.StorePayStub(ctx, paystub)
|
|
|
|
require.NoError(t, err)
|
|
|
|
}
|
2020-03-16 04:28:03 +00:00
|
|
|
|
2021-04-22 19:50:42 +01:00
|
|
|
expected := []payouts.HeldAmountHistory{
|
|
|
|
{
|
|
|
|
SatelliteID: satelliteID1,
|
|
|
|
HeldAmounts: []payouts.HeldForPeriod{
|
|
|
|
{
|
|
|
|
Period: "2021-01",
|
|
|
|
Amount: 10,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Period: "2021-02",
|
|
|
|
Amount: 10,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
SatelliteID: satelliteID2,
|
|
|
|
HeldAmounts: []payouts.HeldForPeriod{
|
|
|
|
{
|
|
|
|
Period: "2021-01",
|
|
|
|
Amount: 0,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Period: "2021-02",
|
|
|
|
Amount: 0,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
SatelliteID: satelliteID3,
|
|
|
|
},
|
2020-03-16 04:28:03 +00:00
|
|
|
}
|
|
|
|
|
2021-07-29 15:30:57 +01:00
|
|
|
service, err := payouts.NewService(log, payoutsDB, db.Reputation(), db.Satellites(), pool)
|
2021-04-22 19:50:42 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
history, err := service.HeldAmountHistory(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.ElementsMatch(t, expected, history)
|
|
|
|
})
|
|
|
|
}
|
2021-07-29 15:30:57 +01:00
|
|
|
|
|
|
|
type fakeSource struct {
|
|
|
|
name string
|
|
|
|
static bool
|
|
|
|
entries []trust.Entry
|
|
|
|
err error
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *fakeSource) String() string {
|
|
|
|
return s.name
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *fakeSource) Static() bool {
|
|
|
|
return s.static
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *fakeSource) FetchEntries(context.Context) ([]trust.Entry, error) {
|
|
|
|
return s.entries, s.err
|
|
|
|
}
|
|
|
|
|
|
|
|
type fakeIdentityResolver struct {
|
|
|
|
mu sync.Mutex
|
|
|
|
identities map[storj.NodeURL]*identity.PeerIdentity
|
|
|
|
}
|
|
|
|
|
|
|
|
func newFakeIdentityResolver() *fakeIdentityResolver {
|
|
|
|
return &fakeIdentityResolver{
|
|
|
|
identities: make(map[storj.NodeURL]*identity.PeerIdentity),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (resolver *fakeIdentityResolver) SetIdentity(url storj.NodeURL, identity *identity.PeerIdentity) {
|
|
|
|
resolver.mu.Lock()
|
|
|
|
defer resolver.mu.Unlock()
|
|
|
|
resolver.identities[url] = identity
|
|
|
|
}
|
|
|
|
|
|
|
|
func (resolver *fakeIdentityResolver) ResolveIdentity(ctx context.Context, url storj.NodeURL) (*identity.PeerIdentity, error) {
|
|
|
|
resolver.mu.Lock()
|
|
|
|
defer resolver.mu.Unlock()
|
|
|
|
|
|
|
|
identity := resolver.identities[url]
|
|
|
|
if identity == nil {
|
|
|
|
return nil, errors.New("no identity")
|
|
|
|
}
|
|
|
|
return identity, nil
|
|
|
|
}
|