2022-05-10 13:18:23 +01:00
|
|
|
// Copyright (C) 2022 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package storjscan_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"math/big"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/zeebo/errs"
|
|
|
|
|
2022-09-06 13:43:09 +01:00
|
|
|
"storj.io/common/currency"
|
2022-05-10 13:18:23 +01:00
|
|
|
"storj.io/common/testcontext"
|
|
|
|
"storj.io/common/testrand"
|
|
|
|
"storj.io/storj/private/blockchain"
|
|
|
|
"storj.io/storj/satellite"
|
2022-06-01 22:59:47 +01:00
|
|
|
"storj.io/storj/satellite/payments"
|
2022-05-10 13:18:23 +01:00
|
|
|
"storj.io/storj/satellite/payments/storjscan"
|
|
|
|
"storj.io/storj/satellite/payments/storjscan/blockchaintest"
|
|
|
|
"storj.io/storj/satellite/satellitedb/satellitedbtest"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestPaymentsDBInsertBatch(t *testing.T) {
|
|
|
|
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
|
|
|
|
paymentsDB := db.StorjscanPayments()
|
|
|
|
now := time.Now().Truncate(time.Second)
|
|
|
|
|
2022-06-01 22:59:47 +01:00
|
|
|
var cachedPayments []storjscan.CachedPayment
|
2022-05-10 13:18:23 +01:00
|
|
|
for i := 0; i < 100; i++ {
|
2022-06-01 22:59:47 +01:00
|
|
|
cachedPayments = append(cachedPayments, storjscan.CachedPayment{
|
2022-05-10 13:18:23 +01:00
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: blockchaintest.NewAddress(),
|
2022-09-06 13:43:09 +01:00
|
|
|
TokenValue: currency.AmountFromBaseUnits(1000, currency.StorjToken),
|
|
|
|
USDValue: currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro),
|
2022-05-10 13:18:23 +01:00
|
|
|
BlockHash: blockchaintest.NewHash(),
|
|
|
|
BlockNumber: int64(i),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
2022-06-01 22:59:47 +01:00
|
|
|
Status: payments.PaymentStatusConfirmed,
|
2022-05-10 13:18:23 +01:00
|
|
|
LogIndex: i,
|
|
|
|
Timestamp: now.Add(time.Duration(i) * time.Second),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-06-01 22:59:47 +01:00
|
|
|
err := paymentsDB.InsertBatch(ctx, cachedPayments)
|
2022-05-10 13:18:23 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPaymentsDBList(t *testing.T) {
|
|
|
|
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
|
|
|
|
paymentsDB := db.StorjscanPayments()
|
|
|
|
now := time.Now().Truncate(time.Second)
|
|
|
|
|
|
|
|
var blocks []blockHeader
|
|
|
|
for i := 0; i < 5; i++ {
|
|
|
|
blocks = append(blocks, blockHeader{
|
|
|
|
Hash: blockchaintest.NewHash(),
|
|
|
|
Number: int64(i),
|
|
|
|
Timestamp: now.Add(time.Duration(i) * time.Second),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
wallet1 := blockchaintest.NewAddress()
|
|
|
|
wallet2 := blockchaintest.NewAddress()
|
|
|
|
tx1 := blockchaintest.NewHash()
|
|
|
|
tx2 := blockchaintest.NewHash()
|
|
|
|
|
|
|
|
expected := []storjscan.CachedPayment{
|
|
|
|
blocks[0].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: wallet1,
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: tx1,
|
|
|
|
Index: 0,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[0].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: wallet1,
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: tx1,
|
|
|
|
Index: 1,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[0].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: wallet1,
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
Index: 2,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[1].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: wallet1,
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
Index: 0,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[1].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: wallet2,
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
Index: 1,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[2].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: wallet2,
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
Index: 0,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[3].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: wallet1,
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
Index: 0,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[4].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: wallet1,
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
Index: 0,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusPending),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[4].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: wallet2,
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: tx2,
|
|
|
|
Index: 1,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusPending),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[4].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: wallet2,
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: tx2,
|
|
|
|
Index: 2,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusPending),
|
2022-05-10 13:18:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
err := paymentsDB.InsertBatch(ctx, expected)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
t.Run("List", func(t *testing.T) {
|
|
|
|
actual, err := paymentsDB.List(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, expected, actual)
|
|
|
|
})
|
|
|
|
t.Run("ListWallet", func(t *testing.T) {
|
|
|
|
var expectedW []storjscan.CachedPayment
|
|
|
|
expectedW = append(expectedW,
|
2022-06-16 14:26:27 +01:00
|
|
|
expected[7], expected[6], expected[3], expected[2], expected[1], expected[0])
|
2022-05-10 13:18:23 +01:00
|
|
|
|
|
|
|
actual, err := paymentsDB.ListWallet(ctx, wallet1, 10, 0)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, expectedW, actual)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPaymentsDBLastBlock(t *testing.T) {
|
|
|
|
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
|
|
|
|
paymentsDB := db.StorjscanPayments()
|
|
|
|
now := time.Now().Truncate(time.Second)
|
|
|
|
|
2022-06-01 22:59:47 +01:00
|
|
|
var cachedPayments []storjscan.CachedPayment
|
2022-05-10 13:18:23 +01:00
|
|
|
for i := 0; i < 10; i++ {
|
2022-06-01 22:59:47 +01:00
|
|
|
cachedPayments = append(cachedPayments, storjscan.CachedPayment{
|
2022-05-10 13:18:23 +01:00
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: blockchaintest.NewAddress(),
|
2022-09-06 13:43:09 +01:00
|
|
|
TokenValue: currency.AmountFromBaseUnits(1000, currency.StorjToken),
|
|
|
|
USDValue: currency.AmountFromBaseUnits(1000, currency.USDollarsMicro),
|
2022-06-01 22:59:47 +01:00
|
|
|
Status: payments.PaymentStatusConfirmed,
|
2022-05-10 13:18:23 +01:00
|
|
|
BlockHash: blockchaintest.NewHash(),
|
|
|
|
BlockNumber: int64(i),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
LogIndex: 100,
|
|
|
|
Timestamp: now.Add(time.Duration(i) * time.Second),
|
|
|
|
})
|
|
|
|
}
|
2022-06-01 22:59:47 +01:00
|
|
|
cachedPayments = append(cachedPayments, storjscan.CachedPayment{
|
2022-05-10 13:18:23 +01:00
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: blockchaintest.NewAddress(),
|
2022-09-06 13:43:09 +01:00
|
|
|
TokenValue: currency.AmountFromBaseUnits(1000, currency.StorjToken),
|
|
|
|
USDValue: currency.AmountFromBaseUnits(1000, currency.USDollarsMicro),
|
2022-06-01 22:59:47 +01:00
|
|
|
Status: payments.PaymentStatusPending,
|
2022-05-10 13:18:23 +01:00
|
|
|
BlockHash: blockchaintest.NewHash(),
|
|
|
|
BlockNumber: int64(10),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
LogIndex: 100,
|
|
|
|
Timestamp: now.Add(time.Duration(10) * time.Second),
|
|
|
|
})
|
|
|
|
|
2022-06-01 22:59:47 +01:00
|
|
|
err := paymentsDB.InsertBatch(ctx, cachedPayments)
|
2022-05-10 13:18:23 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
t.Run("payment status confirmed", func(t *testing.T) {
|
2022-06-01 22:59:47 +01:00
|
|
|
last, err := paymentsDB.LastBlock(ctx, payments.PaymentStatusConfirmed)
|
2022-05-10 13:18:23 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.EqualValues(t, 9, last)
|
|
|
|
})
|
|
|
|
t.Run("payment status pending", func(t *testing.T) {
|
2022-06-01 22:59:47 +01:00
|
|
|
last, err := paymentsDB.LastBlock(ctx, payments.PaymentStatusPending)
|
2022-05-10 13:18:23 +01:00
|
|
|
require.NoError(t, err)
|
|
|
|
require.EqualValues(t, 10, last)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPaymentsDBLastBlockNoPayments(t *testing.T) {
|
|
|
|
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
|
2022-06-01 22:59:47 +01:00
|
|
|
_, err := db.StorjscanPayments().LastBlock(ctx, payments.PaymentStatusConfirmed)
|
2022-05-10 13:18:23 +01:00
|
|
|
require.True(t, errs.Is(err, storjscan.ErrNoPayments))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPaymentsDBDeletePending(t *testing.T) {
|
|
|
|
satellitedbtest.Run(t, func(ctx *testcontext.Context, t *testing.T, db satellite.DB) {
|
|
|
|
paymentsDB := db.StorjscanPayments()
|
|
|
|
now := time.Now().Truncate(time.Second)
|
|
|
|
|
|
|
|
var blocks []blockHeader
|
|
|
|
for i := 0; i < 6; i++ {
|
|
|
|
blocks = append(blocks, blockHeader{
|
|
|
|
Hash: blockchaintest.NewHash(),
|
|
|
|
Number: int64(i),
|
|
|
|
Timestamp: now.Add(time.Duration(i) * time.Second),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
payments := []storjscan.CachedPayment{
|
|
|
|
blocks[0].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: blockchaintest.NewAddress(),
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
Index: 0,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[1].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: blockchaintest.NewAddress(),
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
Index: 0,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[2].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: blockchaintest.NewAddress(),
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
Index: 0,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[3].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: blockchaintest.NewAddress(),
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
Index: 0,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[4].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: blockchaintest.NewAddress(),
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
Index: 0,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusPending),
|
2022-05-10 13:18:23 +01:00
|
|
|
blocks[5].NewPayment(paymentLog{
|
|
|
|
From: blockchaintest.NewAddress(),
|
|
|
|
To: blockchaintest.NewAddress(),
|
|
|
|
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
|
|
|
|
Transaction: blockchaintest.NewHash(),
|
|
|
|
Index: 0,
|
2022-09-06 13:43:09 +01:00
|
|
|
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusPending),
|
2022-05-10 13:18:23 +01:00
|
|
|
}
|
|
|
|
require.NoError(t, paymentsDB.InsertBatch(ctx, payments))
|
|
|
|
|
|
|
|
require.NoError(t, paymentsDB.DeletePending(ctx))
|
|
|
|
actual, err := paymentsDB.List(ctx)
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, 4, len(actual))
|
|
|
|
require.Equal(t, payments[:4], actual)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
type paymentLog struct {
|
|
|
|
From blockchain.Address
|
|
|
|
To blockchain.Address
|
|
|
|
TokenValue *big.Int
|
|
|
|
Transaction blockchain.Hash
|
|
|
|
Index int
|
|
|
|
}
|
|
|
|
|
|
|
|
type blockHeader struct {
|
|
|
|
Hash blockchain.Hash
|
|
|
|
Number int64
|
|
|
|
Timestamp time.Time
|
|
|
|
}
|
|
|
|
|
2022-09-06 13:43:09 +01:00
|
|
|
func (block blockHeader) NewPayment(log paymentLog, usdValue currency.Amount, status payments.PaymentStatus) storjscan.CachedPayment {
|
2022-05-10 13:18:23 +01:00
|
|
|
return storjscan.CachedPayment{
|
|
|
|
From: log.From,
|
|
|
|
To: log.To,
|
2022-09-06 13:43:09 +01:00
|
|
|
TokenValue: currency.AmountFromBaseUnits(log.TokenValue.Int64(), currency.StorjToken),
|
2022-06-23 13:05:19 +01:00
|
|
|
USDValue: usdValue,
|
2022-05-10 13:18:23 +01:00
|
|
|
Status: status,
|
|
|
|
BlockHash: block.Hash,
|
|
|
|
BlockNumber: block.Number,
|
|
|
|
Transaction: log.Transaction,
|
|
|
|
LogIndex: log.Index,
|
2022-07-27 12:36:55 +01:00
|
|
|
Timestamp: block.Timestamp.UTC(),
|
2022-05-10 13:18:23 +01:00
|
|
|
}
|
|
|
|
}
|