storj/satellite/payments/storjscan/paymentsdb_test.go

314 lines
12 KiB
Go
Raw Normal View History

// 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"
"storj.io/common/currency"
"storj.io/common/testcontext"
"storj.io/common/testrand"
"storj.io/storj/private/blockchain"
"storj.io/storj/satellite"
"storj.io/storj/satellite/payments"
"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)
var cachedPayments []storjscan.CachedPayment
for i := 0; i < 100; i++ {
cachedPayments = append(cachedPayments, storjscan.CachedPayment{
From: blockchaintest.NewAddress(),
To: blockchaintest.NewAddress(),
TokenValue: currency.AmountFromBaseUnits(1000, currency.StorjToken),
USDValue: currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro),
BlockHash: blockchaintest.NewHash(),
BlockNumber: int64(i),
Transaction: blockchaintest.NewHash(),
Status: payments.PaymentStatusConfirmed,
LogIndex: i,
Timestamp: now.Add(time.Duration(i) * time.Second),
})
}
err := paymentsDB.InsertBatch(ctx, cachedPayments)
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,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
blocks[0].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: wallet1,
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: tx1,
Index: 1,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
blocks[0].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: wallet1,
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: blockchaintest.NewHash(),
Index: 2,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
blocks[1].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: wallet1,
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: blockchaintest.NewHash(),
Index: 0,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
blocks[1].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: wallet2,
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: blockchaintest.NewHash(),
Index: 1,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
blocks[2].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: wallet2,
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: blockchaintest.NewHash(),
Index: 0,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
blocks[3].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: wallet1,
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: blockchaintest.NewHash(),
Index: 0,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
blocks[4].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: wallet1,
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: blockchaintest.NewHash(),
Index: 0,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusPending),
blocks[4].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: wallet2,
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: tx2,
Index: 1,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusPending),
blocks[4].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: wallet2,
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: tx2,
Index: 2,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusPending),
}
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,
expected[7], expected[6], expected[3], expected[2], expected[1], expected[0])
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)
var cachedPayments []storjscan.CachedPayment
for i := 0; i < 10; i++ {
cachedPayments = append(cachedPayments, storjscan.CachedPayment{
From: blockchaintest.NewAddress(),
To: blockchaintest.NewAddress(),
TokenValue: currency.AmountFromBaseUnits(1000, currency.StorjToken),
USDValue: currency.AmountFromBaseUnits(1000, currency.USDollarsMicro),
Status: payments.PaymentStatusConfirmed,
BlockHash: blockchaintest.NewHash(),
BlockNumber: int64(i),
Transaction: blockchaintest.NewHash(),
LogIndex: 100,
Timestamp: now.Add(time.Duration(i) * time.Second),
})
}
cachedPayments = append(cachedPayments, storjscan.CachedPayment{
From: blockchaintest.NewAddress(),
To: blockchaintest.NewAddress(),
TokenValue: currency.AmountFromBaseUnits(1000, currency.StorjToken),
USDValue: currency.AmountFromBaseUnits(1000, currency.USDollarsMicro),
Status: payments.PaymentStatusPending,
BlockHash: blockchaintest.NewHash(),
BlockNumber: int64(10),
Transaction: blockchaintest.NewHash(),
LogIndex: 100,
Timestamp: now.Add(time.Duration(10) * time.Second),
})
err := paymentsDB.InsertBatch(ctx, cachedPayments)
require.NoError(t, err)
t.Run("payment status confirmed", func(t *testing.T) {
last, err := paymentsDB.LastBlock(ctx, payments.PaymentStatusConfirmed)
require.NoError(t, err)
require.EqualValues(t, 9, last)
})
t.Run("payment status pending", func(t *testing.T) {
last, err := paymentsDB.LastBlock(ctx, payments.PaymentStatusPending)
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) {
_, err := db.StorjscanPayments().LastBlock(ctx, payments.PaymentStatusConfirmed)
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,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
blocks[1].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: blockchaintest.NewAddress(),
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: blockchaintest.NewHash(),
Index: 0,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
blocks[2].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: blockchaintest.NewAddress(),
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: blockchaintest.NewHash(),
Index: 0,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
blocks[3].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: blockchaintest.NewAddress(),
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: blockchaintest.NewHash(),
Index: 0,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusConfirmed),
blocks[4].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: blockchaintest.NewAddress(),
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: blockchaintest.NewHash(),
Index: 0,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusPending),
blocks[5].NewPayment(paymentLog{
From: blockchaintest.NewAddress(),
To: blockchaintest.NewAddress(),
TokenValue: new(big.Int).SetInt64(testrand.Int63n(1000)),
Transaction: blockchaintest.NewHash(),
Index: 0,
}, currency.AmountFromBaseUnits(testrand.Int63n(1000), currency.USDollarsMicro), payments.PaymentStatusPending),
}
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
}
func (block blockHeader) NewPayment(log paymentLog, usdValue currency.Amount, status payments.PaymentStatus) storjscan.CachedPayment {
return storjscan.CachedPayment{
From: log.From,
To: log.To,
TokenValue: currency.AmountFromBaseUnits(log.TokenValue.Int64(), currency.StorjToken),
USDValue: usdValue,
Status: status,
BlockHash: block.Hash,
BlockNumber: block.Number,
Transaction: log.Transaction,
LogIndex: log.Index,
Timestamp: block.Timestamp.UTC(),
}
}