2022-05-10 13:20:29 +01:00
|
|
|
// Copyright (C) 2022 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package storjscan_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math/big"
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
|
|
|
"strconv"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2022-06-23 13:05:19 +01:00
|
|
|
"github.com/shopspring/decimal"
|
2022-05-10 13:20:29 +01:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/zeebo/errs"
|
|
|
|
"go.uber.org/zap/zaptest"
|
|
|
|
|
|
|
|
"storj.io/common/testcontext"
|
|
|
|
"storj.io/storj/satellite"
|
2022-06-01 22:59:47 +01:00
|
|
|
"storj.io/storj/satellite/payments"
|
2022-05-10 13:20:29 +01:00
|
|
|
"storj.io/storj/satellite/payments/monetary"
|
|
|
|
"storj.io/storj/satellite/payments/storjscan"
|
|
|
|
"storj.io/storj/satellite/payments/storjscan/blockchaintest"
|
|
|
|
"storj.io/storj/satellite/payments/storjscan/storjscantest"
|
|
|
|
"storj.io/storj/satellite/satellitedb/satellitedbtest"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestChore(t *testing.T) {
|
|
|
|
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
|
|
|
|
logger := zaptest.NewLogger(t)
|
|
|
|
now := time.Now().Round(time.Second)
|
|
|
|
|
|
|
|
const confirmations = 12
|
|
|
|
|
2022-06-01 22:59:47 +01:00
|
|
|
var pmnts []storjscan.Payment
|
2022-05-10 13:20:29 +01:00
|
|
|
var cachedPayments []storjscan.CachedPayment
|
|
|
|
|
|
|
|
latestBlock := storjscan.Header{
|
|
|
|
Hash: blockchaintest.NewHash(),
|
|
|
|
Number: 0,
|
|
|
|
Timestamp: now,
|
|
|
|
}
|
|
|
|
|
|
|
|
addPayments := func(count int) {
|
2022-06-01 22:59:47 +01:00
|
|
|
l := len(pmnts)
|
2022-05-10 13:20:29 +01:00
|
|
|
for i := l; i < l+count; i++ {
|
|
|
|
payment := storjscan.Payment{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: blockchaintest.NewAddress(),
|
|
|
|
TokenValue: new(big.Int).SetInt64(int64(i)),
|
2022-06-23 13:05:19 +01:00
|
|
|
USDValue: float64(i) + 0.1,
|
2022-05-10 13:20:29 +01:00
|
|
|
BlockHash: blockchaintest.NewHash(),
|
|
|
|
BlockNumber: int64(i),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
LogIndex: i,
|
|
|
|
Timestamp: now.Add(time.Duration(i) * time.Second),
|
|
|
|
}
|
2022-06-01 22:59:47 +01:00
|
|
|
pmnts = append(pmnts, payment)
|
2022-05-10 13:20:29 +01:00
|
|
|
|
|
|
|
cachedPayments = append(cachedPayments, storjscan.CachedPayment{
|
|
|
|
From: payment.From,
|
|
|
|
To: payment.To,
|
|
|
|
TokenValue: monetary.AmountFromBaseUnits(payment.TokenValue.Int64(), monetary.StorjToken),
|
2022-06-23 13:05:19 +01:00
|
|
|
USDValue: monetary.AmountFromDecimal(decimal.NewFromFloat(payment.USDValue), monetary.USDollars),
|
2022-06-01 22:59:47 +01:00
|
|
|
Status: payments.PaymentStatusPending,
|
2022-05-10 13:20:29 +01:00
|
|
|
BlockHash: payment.BlockHash,
|
|
|
|
BlockNumber: payment.BlockNumber,
|
|
|
|
Transaction: payment.Transaction,
|
|
|
|
LogIndex: payment.LogIndex,
|
|
|
|
Timestamp: payment.Timestamp,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
latestBlock = storjscan.Header{
|
2022-06-01 22:59:47 +01:00
|
|
|
Hash: pmnts[len(pmnts)-1].BlockHash,
|
|
|
|
Number: pmnts[len(pmnts)-1].BlockNumber,
|
|
|
|
Timestamp: pmnts[len(pmnts)-1].Timestamp,
|
2022-05-10 13:20:29 +01:00
|
|
|
}
|
|
|
|
for i := 0; i < len(cachedPayments); i++ {
|
|
|
|
if latestBlock.Number-cachedPayments[i].BlockNumber >= confirmations {
|
2022-06-01 22:59:47 +01:00
|
|
|
cachedPayments[i].Status = payments.PaymentStatusConfirmed
|
2022-05-10 13:20:29 +01:00
|
|
|
} else {
|
2022-06-01 22:59:47 +01:00
|
|
|
cachedPayments[i].Status = payments.PaymentStatusPending
|
2022-05-10 13:20:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var reqCounter int
|
|
|
|
|
|
|
|
const (
|
|
|
|
identifier = "eu"
|
|
|
|
secret = "secret"
|
|
|
|
)
|
|
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
var err error
|
|
|
|
reqCounter++
|
|
|
|
|
|
|
|
if err = storjscantest.CheckAuth(r, identifier, secret); err != nil {
|
|
|
|
storjscantest.ServeJSONError(t, w, http.StatusUnauthorized, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
var from int64
|
|
|
|
if s := r.URL.Query().Get("from"); s != "" {
|
|
|
|
from, err = strconv.ParseInt(s, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
storjscantest.ServeJSONError(t, w, http.StatusBadRequest, errs.New("from parameter is missing"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-01 22:59:47 +01:00
|
|
|
storjscantest.ServePayments(t, w, from, latestBlock, pmnts)
|
2022-05-10 13:20:29 +01:00
|
|
|
}))
|
|
|
|
defer server.Close()
|
|
|
|
|
|
|
|
paymentsDB := db.StorjscanPayments()
|
|
|
|
|
|
|
|
client := storjscan.NewClient(server.URL, "eu", "secret")
|
2022-07-08 16:23:56 +01:00
|
|
|
chore := storjscan.NewChore(logger, client, paymentsDB, confirmations, time.Second, false)
|
2022-05-10 13:20:29 +01:00
|
|
|
ctx.Go(func() error {
|
|
|
|
return chore.Run(ctx)
|
|
|
|
})
|
|
|
|
defer ctx.Check(chore.Close)
|
|
|
|
|
|
|
|
chore.TransactionCycle.Pause()
|
|
|
|
chore.TransactionCycle.TriggerWait()
|
|
|
|
cachedReqCounter := reqCounter
|
|
|
|
|
|
|
|
addPayments(100)
|
|
|
|
chore.TransactionCycle.TriggerWait()
|
|
|
|
|
2022-06-01 22:59:47 +01:00
|
|
|
last, err := paymentsDB.LastBlock(ctx, payments.PaymentStatusPending)
|
2022-05-10 13:20:29 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.EqualValues(t, 99, last)
|
|
|
|
actual, err := paymentsDB.List(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, cachedPayments, actual)
|
|
|
|
|
|
|
|
addPayments(100)
|
|
|
|
chore.TransactionCycle.TriggerWait()
|
|
|
|
|
2022-06-01 22:59:47 +01:00
|
|
|
last, err = paymentsDB.LastBlock(ctx, payments.PaymentStatusPending)
|
2022-05-10 13:20:29 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.EqualValues(t, 199, last)
|
|
|
|
actual, err = paymentsDB.List(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, cachedPayments, actual)
|
|
|
|
|
|
|
|
require.Equal(t, reqCounter, cachedReqCounter+2)
|
|
|
|
})
|
|
|
|
}
|