satellite/coinpayments: query status of >25 coinpayments
Allow more than 25 coin payment statuses to be queries from coinpayments.net Add some slight logging, a coinpayments duration metric, and a disabled test These changes are small changes in support of https://storjlabs.atlassian.net/browse/USR-801 Change-Id: I5b176cdd5e513d8bd88b92f9b22a8bd2456bbdd5
This commit is contained in:
parent
4a98c9514c
commit
66661c7486
@ -285,25 +285,32 @@ func (t Transactions) Info(ctx context.Context, id TransactionID) (*TransactionI
|
||||
return txInfo, nil
|
||||
}
|
||||
|
||||
// ListInfos returns up to 25 transaction infos.
|
||||
// ListInfos returns transaction infos.
|
||||
func (t Transactions) ListInfos(ctx context.Context, ids TransactionIDList) (TransactionInfos, error) {
|
||||
if len(ids) > 25 {
|
||||
return nil, Error.New("only up to 25 transactions can be queried")
|
||||
// The service supports a max batch size of 25 items
|
||||
const batchSize = 25
|
||||
var allErrors error
|
||||
numIds := len(ids)
|
||||
txInfos := make(TransactionInfos, numIds)
|
||||
|
||||
for i := 0; i < len(ids); i += batchSize {
|
||||
j := i + batchSize
|
||||
if j > numIds {
|
||||
j = numIds
|
||||
}
|
||||
batchInfos := make(TransactionInfos, j-i)
|
||||
values := make(url.Values, j-i)
|
||||
values.Set("txid", ids[i:j].Encode())
|
||||
res, err := t.client.do(ctx, cmdGetTransactionInfoList, values)
|
||||
if err != nil {
|
||||
allErrors = errs.Combine(allErrors, err)
|
||||
}
|
||||
if err = json.Unmarshal(res, &batchInfos); err != nil {
|
||||
allErrors = errs.Combine(allErrors, err)
|
||||
}
|
||||
for k, v := range batchInfos {
|
||||
txInfos[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
values := make(url.Values)
|
||||
values.Set("txid", ids.Encode())
|
||||
|
||||
txInfos := make(TransactionInfos, len(ids))
|
||||
|
||||
res, err := t.client.do(ctx, cmdGetTransactionInfoList, values)
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
if err = json.Unmarshal(res, &txInfos); err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return txInfos, nil
|
||||
return txInfos, allErrors
|
||||
}
|
||||
|
48
satellite/payments/coinpayments/transactions_test.go
Normal file
48
satellite/payments/coinpayments/transactions_test.go
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (C) 2020 Storj Labs, Inc.
|
||||
// See LICENSE for copying information.
|
||||
|
||||
package coinpayments
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"storj.io/common/testcontext"
|
||||
)
|
||||
|
||||
func TestListInfos(t *testing.T) {
|
||||
//This test is deliberately skipped as it requires credentials to coinpayments.net
|
||||
t.SkipNow()
|
||||
ctx := testcontext.New(t)
|
||||
defer ctx.Cleanup()
|
||||
|
||||
payments := NewClient(Credentials{
|
||||
PublicKey: "ask-littleskunk-on-keybase",
|
||||
PrivateKey: "ask-littleskunk-on-keybase",
|
||||
}).Transactions()
|
||||
|
||||
//verify that bad ids fail
|
||||
infos, err := payments.ListInfos(ctx, TransactionIDList{"an_unlikely_id"})
|
||||
assert.Error(t, err)
|
||||
assert.Len(t, infos, 0)
|
||||
|
||||
//verify that ListInfos can handle more than 25 good ids
|
||||
ids := TransactionIDList{}
|
||||
for x := 0; x < 27; x++ {
|
||||
tx, err := payments.Create(ctx,
|
||||
&CreateTX{
|
||||
Amount: *big.NewFloat(100),
|
||||
CurrencyIn: CurrencySTORJ,
|
||||
CurrencyOut: CurrencySTORJ,
|
||||
BuyerEmail: "test@test.com",
|
||||
},
|
||||
)
|
||||
ids = append(ids, tx.ID)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
infos, err = payments.ListInfos(ctx, ids)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, infos, 27)
|
||||
}
|
@ -150,7 +150,7 @@ func (service *Service) updateTransactionsLoop(ctx context.Context) (err error)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := service.updateTransactions(ctx, txsPage.IDList()); err != nil {
|
||||
if err := service.updateTransactions(ctx, txsPage.IDList(), txsPage.CreationTimes()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -164,7 +164,7 @@ func (service *Service) updateTransactionsLoop(ctx context.Context) (err error)
|
||||
return err
|
||||
}
|
||||
|
||||
if err := service.updateTransactions(ctx, txsPage.IDList()); err != nil {
|
||||
if err := service.updateTransactions(ctx, txsPage.IDList(), txsPage.CreationTimes()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -173,7 +173,7 @@ func (service *Service) updateTransactionsLoop(ctx context.Context) (err error)
|
||||
}
|
||||
|
||||
// updateTransactions updates statuses and received amount for given transactions.
|
||||
func (service *Service) updateTransactions(ctx context.Context, ids TransactionAndUserList) (err error) {
|
||||
func (service *Service) updateTransactions(ctx context.Context, ids TransactionAndUserList, creationTimes map[coinpayments.TransactionID]time.Time) (err error) {
|
||||
defer mon.Task()(&ctx, ids)(&err)
|
||||
|
||||
if len(ids) == 0 {
|
||||
@ -190,6 +190,7 @@ func (service *Service) updateTransactions(ctx context.Context, ids TransactionA
|
||||
var applies coinpayments.TransactionIDList
|
||||
|
||||
for id, info := range infos {
|
||||
service.log.Debug("Coinpayments results: ", zap.String("status", info.Status.String()), zap.String("id", id.String()))
|
||||
updates = append(updates,
|
||||
TransactionUpdate{
|
||||
TransactionID: id,
|
||||
@ -203,6 +204,8 @@ func (service *Service) updateTransactions(ctx context.Context, ids TransactionA
|
||||
// account, so we can apply this amount to customer balance.
|
||||
// Therefore, create intent to update customer balance in the future.
|
||||
if info.Status == coinpayments.StatusCompleted {
|
||||
//monkit currently does not have a DurationVal
|
||||
mon.IntVal("coinpayment_duration").Observe(int64(time.Since(creationTimes[id])))
|
||||
applies = append(applies, id)
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,15 @@ func (page *TransactionsPage) IDList() TransactionAndUserList {
|
||||
return ids
|
||||
}
|
||||
|
||||
// CreationTimes returns a map of creation times of page's transactions.
|
||||
func (page *TransactionsPage) CreationTimes() map[coinpayments.TransactionID]time.Time {
|
||||
var creationTimes map[coinpayments.TransactionID]time.Time
|
||||
for _, tx := range page.Transactions {
|
||||
creationTimes[tx.ID] = tx.CreatedAt
|
||||
}
|
||||
return creationTimes
|
||||
}
|
||||
|
||||
// TransactionAndUserList is a composite type for storing userID and txID
|
||||
type TransactionAndUserList map[coinpayments.TransactionID]uuid.UUID
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user