2023-04-21 11:59:29 +00:00
package activity
import (
2023-06-08 23:52:45 +00:00
"context"
2023-04-21 11:59:29 +00:00
"database/sql"
2023-08-10 11:41:04 +00:00
"fmt"
2023-06-14 19:43:28 +00:00
"math/big"
2023-04-21 11:59:29 +00:00
"testing"
"github.com/status-im/status-go/appdatabase"
2023-05-11 07:50:07 +00:00
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/multiaccounts/accounts"
"github.com/status-im/status-go/services/wallet/common"
2023-04-21 11:59:29 +00:00
"github.com/status-im/status-go/services/wallet/testutils"
"github.com/status-im/status-go/services/wallet/transfer"
2023-08-11 11:28:45 +00:00
"github.com/status-im/status-go/t/helpers"
"github.com/status-im/status-go/walletdatabase"
2023-04-21 11:59:29 +00:00
2023-05-11 07:50:07 +00:00
eth "github.com/ethereum/go-ethereum/common"
2023-06-14 19:43:28 +00:00
"github.com/ethereum/go-ethereum/common/hexutil"
2023-04-21 11:59:29 +00:00
"github.com/stretchr/testify/require"
)
2023-06-13 09:25:23 +00:00
func tokenFromSymbol ( chainID * common . ChainID , symbol string ) * Token {
for i , t := range transfer . TestTokens {
if ( chainID == nil || t . ChainID == uint64 ( * chainID ) ) && t . Symbol == symbol {
tokenType := Erc20
if testutils . SliceContains ( transfer . NativeTokenIndices , i ) {
tokenType = Native
}
return & Token {
TokenType : tokenType ,
ChainID : common . ChainID ( t . ChainID ) ,
Address : t . Address ,
}
}
}
return nil
}
2023-07-10 15:00:35 +00:00
func setupTestActivityDBStorageChoice ( tb testing . TB , inMemory bool ) ( deps FilterDependencies , close func ( ) ) {
2023-08-11 11:28:45 +00:00
var db , appDb * sql . DB
2023-07-10 15:00:35 +00:00
var err error
cleanupDB := func ( ) error { return nil }
2023-08-11 11:28:45 +00:00
cleanupWalletDB := func ( ) error { return nil }
2023-07-10 15:00:35 +00:00
if inMemory {
2023-08-11 11:28:45 +00:00
db , err = helpers . SetupTestMemorySQLDB ( walletdatabase . DbInitializer { } )
require . NoError ( tb , err )
appDb , err = helpers . SetupTestMemorySQLDB ( appdatabase . DbInitializer { } )
require . NoError ( tb , err )
2023-07-10 15:00:35 +00:00
} else {
2023-08-11 11:28:45 +00:00
db , cleanupWalletDB , err = helpers . SetupTestSQLDB ( walletdatabase . DbInitializer { } , "wallet-activity-tests" )
require . NoError ( tb , err )
appDb , cleanupDB , err = helpers . SetupTestSQLDB ( appdatabase . DbInitializer { } , "wallet-activity-tests" )
require . NoError ( tb , err )
2023-07-10 15:00:35 +00:00
}
2023-08-11 11:28:45 +00:00
accountsDb , err := accounts . NewDB ( appDb )
2023-07-10 15:00:35 +00:00
require . NoError ( tb , err )
2023-08-11 11:28:45 +00:00
2023-06-13 09:25:23 +00:00
deps = FilterDependencies {
2023-08-11 11:28:45 +00:00
db : db ,
accountsDb : accountsDb ,
2023-06-13 09:25:23 +00:00
tokenSymbol : func ( token Token ) string {
switch token . TokenType {
case Native :
for i , t := range transfer . TestTokens {
if t . ChainID == uint64 ( token . ChainID ) && testutils . SliceContains ( transfer . NativeTokenIndices , i ) {
return t . Symbol
}
}
case Erc20 :
for _ , t := range transfer . TestTokens {
if t . ChainID == uint64 ( token . ChainID ) && t . Address == token . Address {
return t . Symbol
}
}
}
// In case of ERC721 and ERC1155 we don't have a symbol and they are not yet handled
return ""
} ,
// tokenFromSymbol nil chainID accepts first symbol found
tokenFromSymbol : tokenFromSymbol ,
}
2023-04-21 11:59:29 +00:00
2023-06-13 09:25:23 +00:00
return deps , func ( ) {
2023-07-10 15:00:35 +00:00
require . NoError ( tb , cleanupDB ( ) )
2023-08-11 11:28:45 +00:00
require . NoError ( tb , cleanupWalletDB ( ) )
2023-04-21 11:59:29 +00:00
}
}
2023-07-10 15:00:35 +00:00
func setupTestActivityDB ( tb testing . TB ) ( deps FilterDependencies , close func ( ) ) {
return setupTestActivityDBStorageChoice ( tb , true )
}
2023-04-21 11:59:29 +00:00
type testData struct {
2023-06-13 09:25:23 +00:00
tr1 transfer . TestTransfer // index 1, ETH/Goerli
pendingTr transfer . TestTransfer // index 2, ETH/Optimism
multiTx1Tr1 transfer . TestTransfer // index 3, USDC/Mainnet
multiTx2Tr1 transfer . TestTransfer // index 4, USDC/Goerli
multiTx1Tr2 transfer . TestTransfer // index 5, USDC/Optimism
multiTx2Tr2 transfer . TestTransfer // index 6, SNT/Mainnet
multiTx2PendingTr transfer . TestTransfer // index 7, DAI/Mainnet
2023-06-14 16:10:20 +00:00
multiTx1 transfer . TestMultiTransaction
multiTx1ID transfer . MultiTransactionIDType
multiTx2 transfer . TestMultiTransaction
multiTx2ID transfer . MultiTransactionIDType
nextIndex int
2023-04-21 11:59:29 +00:00
}
2023-08-11 11:28:45 +00:00
func mockTestAccountsWithAddresses ( tb testing . TB , db * accounts . Database , addresses [ ] eth . Address ) {
2023-05-28 10:40:50 +00:00
mockedAccounts := [ ] * accounts . Account { }
for _ , address := range addresses {
mockedAccounts = append ( mockedAccounts , & accounts . Account {
Address : types . Address ( address ) ,
Type : accounts . AccountTypeWatch ,
} )
}
2023-07-10 15:00:35 +00:00
accounts . MockTestAccounts ( tb , db , mockedAccounts )
2023-05-28 10:40:50 +00:00
}
2023-06-14 16:10:20 +00:00
// Generates and adds to the DB 7 transfers and 2 multitransactions.
// There are only 4 extractable activity entries (transactions + multi-transactions) with timestamps 1-4. The others are associated with a multi-transaction
2023-07-10 14:56:08 +00:00
func fillTestData ( t * testing . T , db * sql . DB ) ( td testData , fromAddresses , toAddresses [ ] eth . Address ) {
2023-06-13 09:25:23 +00:00
// Generates ETH/Goerli, ETH/Optimism, USDC/Mainnet, USDC/Goerli, USDC/Optimism, SNT/Mainnet, DAI/Mainnet
2023-06-14 16:10:20 +00:00
trs , fromAddresses , toAddresses := transfer . GenerateTestTransfers ( t , db , 1 , 7 )
// Plain transfer
2023-04-21 11:59:29 +00:00
td . tr1 = trs [ 0 ]
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , db , td . tr1 . To , & td . tr1 )
2023-04-21 11:59:29 +00:00
2023-06-14 16:10:20 +00:00
// Pending transfer
2023-04-21 11:59:29 +00:00
td . pendingTr = trs [ 1 ]
2023-05-11 07:50:07 +00:00
transfer . InsertTestPendingTransaction ( t , db , & td . pendingTr )
2023-04-21 11:59:29 +00:00
2023-06-14 16:10:20 +00:00
// Send Multitransaction containing 2 x Plain transfers
td . multiTx1Tr1 = trs [ 2 ]
td . multiTx1Tr2 = trs [ 4 ]
td . multiTx1 = transfer . GenerateTestSendMultiTransaction ( td . multiTx1Tr1 )
td . multiTx1 . ToToken = testutils . DaiSymbol
td . multiTx1ID = transfer . InsertTestMultiTransaction ( t , db , & td . multiTx1 )
td . multiTx1Tr1 . MultiTransactionID = td . multiTx1ID
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , db , td . multiTx1Tr1 . To , & td . multiTx1Tr1 )
2023-06-14 16:10:20 +00:00
td . multiTx1Tr2 . MultiTransactionID = td . multiTx1ID
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , db , td . multiTx1Tr2 . To , & td . multiTx1Tr2 )
2023-04-21 11:59:29 +00:00
2023-06-14 16:10:20 +00:00
// Send Multitransaction containing 2 x Plain transfers + 1 x Pending transfer
td . multiTx2Tr1 = trs [ 3 ]
td . multiTx2Tr2 = trs [ 5 ]
td . multiTx2PendingTr = trs [ 6 ]
2023-04-21 11:59:29 +00:00
2023-06-14 16:10:20 +00:00
td . multiTx2 = transfer . GenerateTestSendMultiTransaction ( td . multiTx2Tr1 )
2023-06-13 09:25:23 +00:00
td . multiTx2 . ToToken = testutils . SntSymbol
2023-06-14 16:10:20 +00:00
td . multiTx2ID = transfer . InsertTestMultiTransaction ( t , db , & td . multiTx2 )
2023-05-28 10:40:50 +00:00
2023-06-14 16:10:20 +00:00
td . multiTx2Tr1 . MultiTransactionID = td . multiTx2ID
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , db , td . multiTx2Tr1 . To , & td . multiTx2Tr1 )
2023-06-14 16:10:20 +00:00
td . multiTx2Tr2 . MultiTransactionID = td . multiTx2ID
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , db , td . multiTx2Tr2 . To , & td . multiTx2Tr2 )
2023-06-14 16:10:20 +00:00
td . multiTx2PendingTr . MultiTransactionID = td . multiTx2ID
transfer . InsertTestPendingTransaction ( t , db , & td . multiTx2PendingTr )
2023-04-21 11:59:29 +00:00
2023-05-28 10:40:50 +00:00
td . nextIndex = 8
return td , fromAddresses , toAddresses
2023-04-21 11:59:29 +00:00
}
2023-06-13 09:25:23 +00:00
func TTrToToken ( t * testing . T , tt * transfer . TestTransaction ) * Token {
token , isNative := transfer . TestTrToToken ( t , tt )
tokenType := Erc20
if isNative {
tokenType = Native
}
return & Token {
TokenType : tokenType ,
ChainID : common . ChainID ( token . ChainID ) ,
Address : token . Address ,
}
}
2023-07-18 15:57:44 +00:00
func expectedTokenType ( tokenAddress eth . Address ) * TransferType {
transferType := new ( TransferType )
if ( tokenAddress != eth . Address { } ) {
* transferType = TransferTypeErc20
} else {
* transferType = TransferTypeEth
}
return transferType
}
2023-04-21 11:59:29 +00:00
func TestGetActivityEntriesAll ( t * testing . T ) {
2023-06-13 09:25:23 +00:00
deps , close := setupTestActivityDB ( t )
2023-04-21 11:59:29 +00:00
defer close ( )
2023-06-13 09:25:23 +00:00
td , fromAddresses , toAddresses := fillTestData ( t , deps . db )
2023-04-21 11:59:29 +00:00
var filter Filter
2023-06-13 09:25:23 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , append ( toAddresses , fromAddresses ... ) , [ ] common . ChainID { } , filter , 0 , 10 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 4 , len ( entries ) )
// Ensure we have the correct order
var curTimestamp int64 = 4
for _ , entry := range entries {
require . Equal ( t , curTimestamp , entry . timestamp , "entries are sorted by timestamp; expected %d, got %d" , curTimestamp , entry . timestamp )
curTimestamp --
}
2023-06-13 09:25:23 +00:00
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : SimpleTransactionPT ,
2023-07-04 22:21:07 +00:00
transaction : & transfer . TransactionIdentity { ChainID : td . tr1 . ChainID , Hash : td . tr1 . Hash , Address : td . tr1 . To } ,
2023-05-11 07:50:07 +00:00
id : td . tr1 . MultiTransactionID ,
timestamp : td . tr1 . Timestamp ,
2023-05-28 10:40:50 +00:00
activityType : SendAT ,
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( td . tr1 . Value ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : TTrToToken ( t , & td . tr1 . TestTransaction ) ,
tokenIn : nil ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "ETH" ) ,
2023-08-28 09:02:05 +00:00
symbolIn : nil ,
2023-07-18 15:57:44 +00:00
sender : & td . tr1 . From ,
recipient : & td . tr1 . To ,
chainIDOut : & td . tr1 . ChainID ,
chainIDIn : nil ,
transferType : expectedTokenType ( td . tr1 . Token . Address ) ,
2023-06-13 09:25:23 +00:00
} , entries [ 3 ] )
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : PendingTransactionPT ,
transaction : & transfer . TransactionIdentity { ChainID : td . pendingTr . ChainID , Hash : td . pendingTr . Hash } ,
id : td . pendingTr . MultiTransactionID ,
timestamp : td . pendingTr . Timestamp ,
2023-05-28 10:40:50 +00:00
activityType : SendAT ,
2023-05-11 07:50:07 +00:00
activityStatus : PendingAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( td . pendingTr . Value ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : TTrToToken ( t , & td . pendingTr . TestTransaction ) ,
tokenIn : nil ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "ETH" ) ,
2023-08-28 09:02:05 +00:00
symbolIn : nil ,
2023-07-18 15:57:44 +00:00
sender : & td . pendingTr . From ,
recipient : & td . pendingTr . To ,
chainIDOut : & td . pendingTr . ChainID ,
chainIDIn : nil ,
transferType : expectedTokenType ( eth . Address { } ) ,
2023-06-13 09:25:23 +00:00
} , entries [ 2 ] )
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : MultiTransactionPT ,
transaction : nil ,
2023-06-14 16:10:20 +00:00
id : td . multiTx1ID ,
timestamp : td . multiTx1 . Timestamp ,
2023-05-11 07:50:07 +00:00
activityType : SendAT ,
2023-05-28 10:40:50 +00:00
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( td . multiTx1 . FromAmount ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( td . multiTx1 . ToAmount ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : tokenFromSymbol ( nil , td . multiTx1 . FromToken ) ,
tokenIn : tokenFromSymbol ( nil , td . multiTx1 . ToToken ) ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "USDC" ) ,
symbolIn : common . NewAndSet ( "DAI" ) ,
2023-07-18 15:57:44 +00:00
sender : & td . multiTx1 . FromAddress ,
recipient : & td . multiTx1 . ToAddress ,
2023-06-13 09:25:23 +00:00
} , entries [ 1 ] )
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : MultiTransactionPT ,
transaction : nil ,
2023-06-14 16:10:20 +00:00
id : td . multiTx2ID ,
timestamp : td . multiTx2 . Timestamp ,
2023-05-11 07:50:07 +00:00
activityType : SendAT ,
2023-05-28 10:40:50 +00:00
activityStatus : PendingAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( td . multiTx2 . FromAmount ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( td . multiTx2 . ToAmount ) ) ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "USDC" ) ,
symbolIn : common . NewAndSet ( "SNT" ) ,
2023-06-13 09:25:23 +00:00
tokenOut : tokenFromSymbol ( nil , td . multiTx2 . FromToken ) ,
tokenIn : tokenFromSymbol ( nil , td . multiTx2 . ToToken ) ,
2023-07-18 15:57:44 +00:00
sender : & td . multiTx2 . FromAddress ,
recipient : & td . multiTx2 . ToAddress ,
2023-06-13 09:25:23 +00:00
} , entries [ 0 ] )
2023-04-21 11:59:29 +00:00
}
// TestGetActivityEntriesWithSenderFilter covers the issue with returning the same transaction
// twice when the sender and receiver have entries in the transfers table
func TestGetActivityEntriesWithSameTransactionForSenderAndReceiverInDB ( t * testing . T ) {
2023-06-13 09:25:23 +00:00
deps , close := setupTestActivityDB ( t )
2023-04-21 11:59:29 +00:00
defer close ( )
// Add 4 extractable transactions with timestamps 1-4
2023-06-13 09:25:23 +00:00
td , fromAddresses , toAddresses := fillTestData ( t , deps . db )
2023-05-28 10:40:50 +00:00
2023-08-11 11:28:45 +00:00
mockTestAccountsWithAddresses ( t , deps . accountsDb , append ( fromAddresses , toAddresses ... ) )
2023-05-28 10:40:50 +00:00
2023-04-21 11:59:29 +00:00
// Add another transaction with sender and receiver reversed
receiverTr := td . tr1
prevTo := receiverTr . To
receiverTr . To = td . tr1 . From
receiverTr . From = prevTo
2023-05-11 07:50:07 +00:00
// TODO: test also when there is a transaction in the other direction
// Ensure they are the oldest transactions (last in the list) and we have a consistent order
receiverTr . Timestamp --
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , deps . db , receiverTr . To , & receiverTr )
2023-04-21 11:59:29 +00:00
var filter Filter
2023-06-13 09:25:23 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { td . tr1 . From , receiverTr . From } , [ ] common . ChainID { } , filter , 0 , 10 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
require . Equal ( t , 2 , len ( entries ) )
// Check that the transaction are labeled alternatively as send and receive
require . Equal ( t , ReceiveAT , entries [ 1 ] . activityType )
require . NotEqual ( t , eth . Address { } , entries [ 1 ] . transaction . Address )
require . Equal ( t , receiverTr . To , entries [ 1 ] . transaction . Address )
require . Equal ( t , SendAT , entries [ 0 ] . activityType )
require . NotEqual ( t , eth . Address { } , entries [ 0 ] . transaction . Address )
2023-07-25 16:03:33 +00:00
require . Equal ( t , td . tr1 . To , * entries [ 0 ] . recipient )
2023-05-11 07:50:07 +00:00
2023-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 10 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 5 , len ( entries ) )
2023-05-11 07:50:07 +00:00
// Check that the transaction are labeled alternatively as send and receive
require . Equal ( t , ReceiveAT , entries [ 4 ] . activityType )
require . Equal ( t , SendAT , entries [ 3 ] . activityType )
2023-04-21 11:59:29 +00:00
}
func TestGetActivityEntriesFilterByTime ( t * testing . T ) {
2023-06-13 09:25:23 +00:00
deps , close := setupTestActivityDB ( t )
2023-04-21 11:59:29 +00:00
defer close ( )
2023-06-13 09:25:23 +00:00
td , fromTds , toTds := fillTestData ( t , deps . db )
2023-05-28 10:40:50 +00:00
2023-04-21 11:59:29 +00:00
// Add 6 extractable transactions with timestamps 6-12
2023-06-13 09:25:23 +00:00
trs , fromTrs , toTrs := transfer . GenerateTestTransfers ( t , deps . db , td . nextIndex , 6 )
2023-04-21 11:59:29 +00:00
for i := range trs {
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , deps . db , trs [ i ] . To , & trs [ i ] )
2023-04-21 11:59:29 +00:00
}
2023-08-11 11:28:45 +00:00
mockTestAccountsWithAddresses ( t , deps . accountsDb , append ( append ( append ( fromTds , toTds ... ) , fromTrs ... ) , toTrs ... ) )
2023-05-28 10:40:50 +00:00
2023-04-21 11:59:29 +00:00
// Test start only
var filter Filter
2023-06-14 16:10:20 +00:00
filter . Period . StartTimestamp = td . multiTx1 . Timestamp
2023-05-11 07:50:07 +00:00
filter . Period . EndTimestamp = NoLimitTimestampForPeriod
2023-07-10 14:56:08 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 8 , len ( entries ) )
2023-07-18 15:57:44 +00:00
2023-04-21 11:59:29 +00:00
// Check start and end content
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : SimpleTransactionPT ,
2023-07-04 22:21:07 +00:00
transaction : & transfer . TransactionIdentity { ChainID : trs [ 5 ] . ChainID , Hash : trs [ 5 ] . Hash , Address : trs [ 5 ] . To } ,
2023-05-11 07:50:07 +00:00
id : 0 ,
timestamp : trs [ 5 ] . Timestamp ,
2023-05-28 10:40:50 +00:00
activityType : SendAT ,
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( trs [ 5 ] . Value ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : TTrToToken ( t , & trs [ 5 ] . TestTransaction ) ,
tokenIn : nil ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "USDC" ) ,
2023-08-28 09:02:05 +00:00
symbolIn : nil ,
2023-07-18 15:57:44 +00:00
sender : & trs [ 5 ] . From ,
recipient : & trs [ 5 ] . To ,
chainIDOut : & trs [ 5 ] . ChainID ,
chainIDIn : nil ,
transferType : expectedTokenType ( trs [ 5 ] . Token . Address ) ,
2023-04-21 11:59:29 +00:00
} , entries [ 0 ] )
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : MultiTransactionPT ,
transaction : nil ,
2023-06-14 16:10:20 +00:00
id : td . multiTx1ID ,
timestamp : td . multiTx1 . Timestamp ,
2023-05-11 07:50:07 +00:00
activityType : SendAT ,
2023-05-28 10:40:50 +00:00
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( td . multiTx1 . FromAmount ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( td . multiTx1 . ToAmount ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : tokenFromSymbol ( nil , td . multiTx1 . FromToken ) ,
tokenIn : tokenFromSymbol ( nil , td . multiTx1 . ToToken ) ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "USDC" ) ,
symbolIn : common . NewAndSet ( "DAI" ) ,
2023-07-18 15:57:44 +00:00
sender : & td . multiTx1 . FromAddress ,
recipient : & td . multiTx1 . ToAddress ,
chainIDOut : nil ,
chainIDIn : nil ,
transferType : nil ,
2023-04-21 11:59:29 +00:00
} , entries [ 7 ] )
// Test complete interval
filter . Period . EndTimestamp = trs [ 2 ] . Timestamp
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 5 , len ( entries ) )
2023-07-18 15:57:44 +00:00
2023-04-21 11:59:29 +00:00
// Check start and end content
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : SimpleTransactionPT ,
2023-07-04 22:21:07 +00:00
transaction : & transfer . TransactionIdentity { ChainID : trs [ 2 ] . ChainID , Hash : trs [ 2 ] . Hash , Address : trs [ 2 ] . To } ,
2023-05-11 07:50:07 +00:00
id : 0 ,
timestamp : trs [ 2 ] . Timestamp ,
2023-05-28 10:40:50 +00:00
activityType : SendAT ,
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( trs [ 2 ] . Value ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : TTrToToken ( t , & trs [ 2 ] . TestTransaction ) ,
tokenIn : nil ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "ETH" ) ,
2023-08-28 09:02:05 +00:00
symbolIn : nil ,
2023-07-18 15:57:44 +00:00
sender : & trs [ 2 ] . From ,
recipient : & trs [ 2 ] . To ,
chainIDOut : & trs [ 2 ] . ChainID ,
chainIDIn : nil ,
transferType : expectedTokenType ( trs [ 2 ] . Token . Address ) ,
2023-04-21 11:59:29 +00:00
} , entries [ 0 ] )
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : MultiTransactionPT ,
transaction : nil ,
2023-06-14 16:10:20 +00:00
id : td . multiTx1ID ,
timestamp : td . multiTx1 . Timestamp ,
2023-05-11 07:50:07 +00:00
activityType : SendAT ,
2023-05-28 10:40:50 +00:00
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( td . multiTx1 . FromAmount ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( td . multiTx1 . ToAmount ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : tokenFromSymbol ( nil , td . multiTx1 . FromToken ) ,
tokenIn : tokenFromSymbol ( nil , td . multiTx1 . ToToken ) ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "USDC" ) ,
symbolIn : common . NewAndSet ( "DAI" ) ,
2023-07-18 15:57:44 +00:00
sender : & td . multiTx1 . FromAddress ,
recipient : & td . multiTx1 . ToAddress ,
chainIDOut : nil ,
chainIDIn : nil ,
transferType : nil ,
2023-04-21 11:59:29 +00:00
} , entries [ 4 ] )
// Test end only
2023-05-11 07:50:07 +00:00
filter . Period . StartTimestamp = NoLimitTimestampForPeriod
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 7 , len ( entries ) )
// Check start and end content
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : SimpleTransactionPT ,
2023-07-04 22:21:07 +00:00
transaction : & transfer . TransactionIdentity { ChainID : trs [ 2 ] . ChainID , Hash : trs [ 2 ] . Hash , Address : trs [ 2 ] . To } ,
2023-05-11 07:50:07 +00:00
id : 0 ,
timestamp : trs [ 2 ] . Timestamp ,
2023-05-28 10:40:50 +00:00
activityType : SendAT ,
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( trs [ 2 ] . Value ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : TTrToToken ( t , & trs [ 2 ] . TestTransaction ) ,
tokenIn : nil ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "ETH" ) ,
2023-08-28 09:02:05 +00:00
symbolIn : nil ,
2023-07-18 15:57:44 +00:00
sender : & trs [ 2 ] . From ,
recipient : & trs [ 2 ] . To ,
chainIDOut : & trs [ 2 ] . ChainID ,
chainIDIn : nil ,
transferType : expectedTokenType ( trs [ 2 ] . Token . Address ) ,
2023-04-21 11:59:29 +00:00
} , entries [ 0 ] )
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : SimpleTransactionPT ,
2023-07-04 22:21:07 +00:00
transaction : & transfer . TransactionIdentity { ChainID : td . tr1 . ChainID , Hash : td . tr1 . Hash , Address : td . tr1 . To } ,
2023-05-11 07:50:07 +00:00
id : 0 ,
timestamp : td . tr1 . Timestamp ,
2023-05-28 10:40:50 +00:00
activityType : SendAT ,
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( td . tr1 . Value ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : TTrToToken ( t , & td . tr1 . TestTransaction ) ,
tokenIn : nil ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "ETH" ) ,
2023-08-28 09:02:05 +00:00
symbolIn : nil ,
2023-07-18 15:57:44 +00:00
sender : & td . tr1 . From ,
recipient : & td . tr1 . To ,
chainIDOut : & td . tr1 . ChainID ,
chainIDIn : nil ,
transferType : expectedTokenType ( td . tr1 . Token . Address ) ,
2023-04-21 11:59:29 +00:00
} , entries [ 6 ] )
}
func TestGetActivityEntriesCheckOffsetAndLimit ( t * testing . T ) {
2023-06-13 09:25:23 +00:00
deps , close := setupTestActivityDB ( t )
2023-04-21 11:59:29 +00:00
defer close ( )
// Add 10 extractable transactions with timestamps 1-10
2023-06-13 09:25:23 +00:00
trs , fromTrs , toTrs := transfer . GenerateTestTransfers ( t , deps . db , 1 , 10 )
2023-04-21 11:59:29 +00:00
for i := range trs {
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , deps . db , trs [ i ] . To , & trs [ i ] )
2023-04-21 11:59:29 +00:00
}
2023-08-11 11:28:45 +00:00
mockTestAccountsWithAddresses ( t , deps . accountsDb , append ( fromTrs , toTrs ... ) )
2023-05-28 10:40:50 +00:00
2023-04-21 11:59:29 +00:00
var filter Filter
// Get all
2023-07-10 14:56:08 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 5 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 5 , len ( entries ) )
// Get time based interval
filter . Period . StartTimestamp = trs [ 2 ] . Timestamp
filter . Period . EndTimestamp = trs [ 8 ] . Timestamp
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 3 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 3 , len ( entries ) )
// Check start and end content
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : SimpleTransactionPT ,
2023-07-04 22:21:07 +00:00
transaction : & transfer . TransactionIdentity { ChainID : trs [ 8 ] . ChainID , Hash : trs [ 8 ] . Hash , Address : trs [ 8 ] . To } ,
2023-05-11 07:50:07 +00:00
id : 0 ,
timestamp : trs [ 8 ] . Timestamp ,
2023-05-28 10:40:50 +00:00
activityType : SendAT ,
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( trs [ 8 ] . Value ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : TTrToToken ( t , & trs [ 8 ] . TestTransaction ) ,
tokenIn : nil ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "ETH" ) ,
2023-08-28 09:02:05 +00:00
symbolIn : nil ,
2023-07-18 15:57:44 +00:00
sender : & trs [ 8 ] . From ,
recipient : & trs [ 8 ] . To ,
chainIDOut : & trs [ 8 ] . ChainID ,
chainIDIn : nil ,
transferType : expectedTokenType ( trs [ 8 ] . Token . Address ) ,
2023-04-21 11:59:29 +00:00
} , entries [ 0 ] )
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : SimpleTransactionPT ,
2023-07-04 22:21:07 +00:00
transaction : & transfer . TransactionIdentity { ChainID : trs [ 6 ] . ChainID , Hash : trs [ 6 ] . Hash , Address : trs [ 6 ] . To } ,
2023-05-11 07:50:07 +00:00
id : 0 ,
timestamp : trs [ 6 ] . Timestamp ,
2023-05-28 10:40:50 +00:00
activityType : SendAT ,
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( trs [ 6 ] . Value ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : TTrToToken ( t , & trs [ 6 ] . TestTransaction ) ,
tokenIn : nil ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "DAI" ) ,
2023-08-28 09:02:05 +00:00
symbolIn : nil ,
2023-07-18 15:57:44 +00:00
sender : & trs [ 6 ] . From ,
recipient : & trs [ 6 ] . To ,
chainIDOut : & trs [ 6 ] . ChainID ,
chainIDIn : nil ,
transferType : expectedTokenType ( trs [ 6 ] . Token . Address ) ,
2023-04-21 11:59:29 +00:00
} , entries [ 2 ] )
// Move window 2 entries forward
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 2 , 3 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 3 , len ( entries ) )
// Check start and end content
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : SimpleTransactionPT ,
2023-07-04 22:21:07 +00:00
transaction : & transfer . TransactionIdentity { ChainID : trs [ 6 ] . ChainID , Hash : trs [ 6 ] . Hash , Address : trs [ 6 ] . To } ,
2023-05-11 07:50:07 +00:00
id : 0 ,
timestamp : trs [ 6 ] . Timestamp ,
2023-05-28 10:40:50 +00:00
activityType : SendAT ,
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( trs [ 6 ] . Value ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : TTrToToken ( t , & trs [ 6 ] . TestTransaction ) ,
tokenIn : nil ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "DAI" ) ,
2023-08-28 09:02:05 +00:00
symbolIn : nil ,
2023-07-18 15:57:44 +00:00
sender : & trs [ 6 ] . From ,
recipient : & trs [ 6 ] . To ,
chainIDOut : & trs [ 6 ] . ChainID ,
chainIDIn : nil ,
transferType : expectedTokenType ( trs [ 6 ] . Token . Address ) ,
2023-04-21 11:59:29 +00:00
} , entries [ 0 ] )
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : SimpleTransactionPT ,
2023-07-04 22:21:07 +00:00
transaction : & transfer . TransactionIdentity { ChainID : trs [ 4 ] . ChainID , Hash : trs [ 4 ] . Hash , Address : trs [ 4 ] . To } ,
2023-05-11 07:50:07 +00:00
id : 0 ,
timestamp : trs [ 4 ] . Timestamp ,
2023-05-28 10:40:50 +00:00
activityType : SendAT ,
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( trs [ 4 ] . Value ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : TTrToToken ( t , & trs [ 4 ] . TestTransaction ) ,
tokenIn : nil ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "USDC" ) ,
2023-08-28 09:02:05 +00:00
symbolIn : nil ,
2023-07-18 15:57:44 +00:00
sender : & trs [ 4 ] . From ,
recipient : & trs [ 4 ] . To ,
chainIDOut : & trs [ 4 ] . ChainID ,
chainIDIn : nil ,
transferType : expectedTokenType ( trs [ 4 ] . Token . Address ) ,
2023-04-21 11:59:29 +00:00
} , entries [ 2 ] )
// Move window 4 more entries to test filter cap
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 6 , 3 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 1 , len ( entries ) )
// Check start and end content
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : SimpleTransactionPT ,
2023-07-04 22:21:07 +00:00
transaction : & transfer . TransactionIdentity { ChainID : trs [ 2 ] . ChainID , Hash : trs [ 2 ] . Hash , Address : trs [ 2 ] . To } ,
2023-05-11 07:50:07 +00:00
id : 0 ,
timestamp : trs [ 2 ] . Timestamp ,
2023-05-28 10:40:50 +00:00
activityType : SendAT ,
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( trs [ 2 ] . Value ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : TTrToToken ( t , & trs [ 2 ] . TestTransaction ) ,
tokenIn : nil ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "USDC" ) ,
2023-08-28 09:02:05 +00:00
symbolIn : nil ,
2023-07-18 15:57:44 +00:00
sender : & trs [ 2 ] . From ,
recipient : & trs [ 2 ] . To ,
chainIDOut : & trs [ 2 ] . ChainID ,
chainIDIn : nil ,
transferType : expectedTokenType ( trs [ 2 ] . Token . Address ) ,
2023-04-21 11:59:29 +00:00
} , entries [ 0 ] )
}
2023-05-28 10:40:50 +00:00
func countTypes ( entries [ ] Entry ) ( sendCount , receiveCount , swapCount , buyCount , bridgeCount int ) {
for _ , entry := range entries {
switch entry . activityType {
case SendAT :
sendCount ++
case ReceiveAT :
receiveCount ++
case SwapAT :
swapCount ++
case BuyAT :
buyCount ++
case BridgeAT :
bridgeCount ++
}
}
return
}
2023-04-21 11:59:29 +00:00
func TestGetActivityEntriesFilterByType ( t * testing . T ) {
2023-06-13 09:25:23 +00:00
deps , close := setupTestActivityDB ( t )
2023-04-21 11:59:29 +00:00
defer close ( )
// Adds 4 extractable transactions
2023-06-13 09:25:23 +00:00
td , _ , _ := fillTestData ( t , deps . db )
2023-05-28 10:40:50 +00:00
// Add 5 extractable transactions: one MultiTransactionSwap, two MultiTransactionBridge and two MultiTransactionSend
2023-06-14 16:10:20 +00:00
multiTxs := make ( [ ] transfer . TestMultiTransaction , 5 )
2023-06-13 09:25:23 +00:00
trs , _ , _ := transfer . GenerateTestTransfers ( t , deps . db , td . nextIndex , len ( multiTxs ) * 2 )
2023-06-14 16:10:20 +00:00
multiTxs [ 0 ] = transfer . GenerateTestBridgeMultiTransaction ( trs [ 0 ] , trs [ 1 ] )
multiTxs [ 1 ] = transfer . GenerateTestSwapMultiTransaction ( trs [ 2 ] , testutils . SntSymbol , 100 ) // trs[3]
multiTxs [ 2 ] = transfer . GenerateTestSendMultiTransaction ( trs [ 4 ] ) // trs[5]
multiTxs [ 3 ] = transfer . GenerateTestBridgeMultiTransaction ( trs [ 6 ] , trs [ 7 ] )
multiTxs [ 4 ] = transfer . GenerateTestSendMultiTransaction ( trs [ 8 ] ) // trs[9]
2023-05-28 10:40:50 +00:00
var lastMT transfer . MultiTransactionIDType
2023-04-21 11:59:29 +00:00
for i := range trs {
2023-05-28 10:40:50 +00:00
if i % 2 == 0 {
2023-06-13 09:25:23 +00:00
lastMT = transfer . InsertTestMultiTransaction ( t , deps . db , & multiTxs [ i / 2 ] )
2023-04-21 11:59:29 +00:00
}
2023-06-14 16:10:20 +00:00
trs [ i ] . MultiTransactionID = lastMT
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , deps . db , trs [ i ] . To , & trs [ i ] )
2023-04-21 11:59:29 +00:00
}
// Test filtering out without address involved
var filter Filter
2023-05-11 07:50:07 +00:00
filter . Types = allActivityTypesFilter ( )
2023-05-28 10:40:50 +00:00
// Set tr1 to Receive and pendingTr to Send; rest of two MT remain default Send
2023-07-10 14:56:08 +00:00
addresses := [ ] eth . Address { td . tr1 . To , td . pendingTr . From , td . multiTx1 . FromAddress , td . multiTx2 . FromAddress , trs [ 0 ] . From , trs [ 2 ] . From , trs [ 4 ] . From , trs [ 6 ] . From , trs [ 8 ] . From }
2023-06-13 09:25:23 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , addresses , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
2023-05-28 10:40:50 +00:00
require . Equal ( t , 9 , len ( entries ) )
2023-05-11 07:50:07 +00:00
2023-04-21 11:59:29 +00:00
filter . Types = [ ] Type { SendAT , SwapAT }
2023-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , addresses , [ ] common . ChainID { } , filter , 0 , 15 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
2023-05-28 10:40:50 +00:00
// 3 from td Send + 2 trs MT Send + 1 (swap)
require . Equal ( t , 6 , len ( entries ) )
sendCount , receiveCount , swapCount , _ , bridgeCount := countTypes ( entries )
require . Equal ( t , 5 , sendCount )
require . Equal ( t , 0 , receiveCount )
2023-04-21 11:59:29 +00:00
require . Equal ( t , 1 , swapCount )
2023-05-28 10:40:50 +00:00
require . Equal ( t , 0 , bridgeCount )
2023-04-21 11:59:29 +00:00
filter . Types = [ ] Type { BridgeAT , ReceiveAT }
2023-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , addresses , [ ] common . ChainID { } , filter , 0 , 15 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 3 , len ( entries ) )
2023-05-28 10:40:50 +00:00
sendCount , receiveCount , swapCount , _ , bridgeCount = countTypes ( entries )
require . Equal ( t , 0 , sendCount )
2023-04-21 11:59:29 +00:00
require . Equal ( t , 1 , receiveCount )
2023-05-28 10:40:50 +00:00
require . Equal ( t , 0 , swapCount )
require . Equal ( t , 2 , bridgeCount )
2023-04-21 11:59:29 +00:00
}
2023-05-11 07:50:07 +00:00
func TestGetActivityEntriesFilterByAddresses ( t * testing . T ) {
2023-06-13 09:25:23 +00:00
deps , close := setupTestActivityDB ( t )
2023-04-21 11:59:29 +00:00
defer close ( )
// Adds 4 extractable transactions
2023-06-13 09:25:23 +00:00
td , fromTds , toTds := fillTestData ( t , deps . db )
trs , fromTrs , toTrs := transfer . GenerateTestTransfers ( t , deps . db , td . nextIndex , 6 )
2023-04-21 11:59:29 +00:00
for i := range trs {
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , deps . db , trs [ i ] . To , & trs [ i ] )
2023-04-21 11:59:29 +00:00
}
2023-08-11 11:28:45 +00:00
mockTestAccountsWithAddresses ( t , deps . accountsDb , append ( append ( append ( fromTds , toTds ... ) , fromTrs ... ) , toTrs ... ) )
2023-05-28 10:40:50 +00:00
2023-04-21 11:59:29 +00:00
var filter Filter
2023-05-11 07:50:07 +00:00
addressesFilter := allAddressesFilter ( )
2023-06-13 09:25:23 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , addressesFilter , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
require . Equal ( t , 10 , len ( entries ) )
2023-07-10 14:56:08 +00:00
addressesFilter = [ ] eth . Address { td . multiTx2 . ToAddress , trs [ 1 ] . From , trs [ 4 ] . To }
2023-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , addressesFilter , [ ] common . ChainID { } , filter , 0 , 15 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 3 , len ( entries ) )
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : SimpleTransactionPT ,
transaction : & transfer . TransactionIdentity { ChainID : trs [ 4 ] . ChainID , Hash : trs [ 4 ] . Hash , Address : trs [ 4 ] . To } ,
id : 0 ,
timestamp : trs [ 4 ] . Timestamp ,
activityType : ReceiveAT ,
2023-05-28 10:40:50 +00:00
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( trs [ 4 ] . Value ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : nil ,
tokenIn : TTrToToken ( t , & trs [ 4 ] . TestTransaction ) ,
2023-08-28 09:02:05 +00:00
symbolOut : nil ,
2023-08-30 16:14:57 +00:00
symbolIn : common . NewAndSet ( "USDC" ) ,
2023-07-18 15:57:44 +00:00
sender : & trs [ 4 ] . From ,
recipient : & trs [ 4 ] . To ,
chainIDOut : nil ,
chainIDIn : & trs [ 4 ] . ChainID ,
transferType : expectedTokenType ( trs [ 4 ] . Token . Address ) ,
2023-04-21 11:59:29 +00:00
} , entries [ 0 ] )
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : SimpleTransactionPT ,
2023-07-04 22:21:07 +00:00
transaction : & transfer . TransactionIdentity { ChainID : trs [ 1 ] . ChainID , Hash : trs [ 1 ] . Hash , Address : trs [ 1 ] . To } ,
2023-05-11 07:50:07 +00:00
id : 0 ,
timestamp : trs [ 1 ] . Timestamp ,
activityType : SendAT ,
2023-05-28 10:40:50 +00:00
activityStatus : CompleteAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( trs [ 1 ] . Value ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( 0 ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : TTrToToken ( t , & trs [ 1 ] . TestTransaction ) ,
tokenIn : nil ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "ETH" ) ,
2023-08-28 09:02:05 +00:00
symbolIn : nil ,
2023-07-18 15:57:44 +00:00
sender : & trs [ 1 ] . From ,
recipient : & trs [ 1 ] . To ,
chainIDOut : & trs [ 1 ] . ChainID ,
chainIDIn : nil ,
transferType : expectedTokenType ( trs [ 1 ] . Token . Address ) ,
2023-04-21 11:59:29 +00:00
} , entries [ 1 ] )
require . Equal ( t , Entry {
2023-05-11 07:50:07 +00:00
payloadType : MultiTransactionPT ,
transaction : nil ,
2023-06-14 16:10:20 +00:00
id : td . multiTx2ID ,
timestamp : td . multiTx2 . Timestamp ,
2023-05-11 07:50:07 +00:00
activityType : SendAT ,
2023-05-28 10:40:50 +00:00
activityStatus : PendingAS ,
2023-06-14 19:43:28 +00:00
amountOut : ( * hexutil . Big ) ( big . NewInt ( td . multiTx2 . FromAmount ) ) ,
amountIn : ( * hexutil . Big ) ( big . NewInt ( td . multiTx2 . ToAmount ) ) ,
2023-06-13 09:25:23 +00:00
tokenOut : tokenFromSymbol ( nil , td . multiTx2 . FromToken ) ,
tokenIn : tokenFromSymbol ( nil , td . multiTx2 . ToToken ) ,
2023-08-30 16:14:57 +00:00
symbolOut : common . NewAndSet ( "USDC" ) ,
symbolIn : common . NewAndSet ( "SNT" ) ,
2023-07-18 15:57:44 +00:00
sender : & td . multiTx2 . FromAddress ,
recipient : & td . multiTx2 . ToAddress ,
chainIDOut : nil ,
chainIDIn : nil ,
2023-04-21 11:59:29 +00:00
} , entries [ 2 ] )
}
2023-05-11 07:50:07 +00:00
func TestGetActivityEntriesFilterByStatus ( t * testing . T ) {
2023-06-13 09:25:23 +00:00
deps , close := setupTestActivityDB ( t )
2023-05-11 07:50:07 +00:00
defer close ( )
2023-05-28 10:40:50 +00:00
// Adds 4 extractable transactions: 1 T, 1 T pending, 1 MT pending, 1 MT with 2xT success
2023-06-13 09:25:23 +00:00
td , fromTds , toTds := fillTestData ( t , deps . db )
2023-05-28 10:40:50 +00:00
// Add 7 extractable transactions: 1 pending, 1 Tr failed, 1 MT failed, 4 success
2023-06-13 09:25:23 +00:00
trs , fromTrs , toTrs := transfer . GenerateTestTransfers ( t , deps . db , td . nextIndex , 7 )
2023-06-14 16:10:20 +00:00
multiTx := transfer . GenerateTestSendMultiTransaction ( trs [ 6 ] )
2023-06-13 09:25:23 +00:00
failedMTID := transfer . InsertTestMultiTransaction ( t , deps . db , & multiTx )
2023-05-28 10:40:50 +00:00
trs [ 6 ] . MultiTransactionID = failedMTID
2023-05-11 07:50:07 +00:00
for i := range trs {
2023-05-28 10:40:50 +00:00
if i == 1 {
2023-06-13 09:25:23 +00:00
transfer . InsertTestPendingTransaction ( t , deps . db , & trs [ i ] )
2023-05-28 10:40:50 +00:00
} else {
trs [ i ] . Success = i != 3 && i != 6
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , deps . db , trs [ i ] . To , & trs [ i ] )
2023-05-28 10:40:50 +00:00
}
2023-05-11 07:50:07 +00:00
}
2023-08-11 11:28:45 +00:00
mockTestAccountsWithAddresses ( t , deps . accountsDb , append ( append ( append ( fromTds , toTds ... ) , fromTrs ... ) , toTrs ... ) )
2023-05-28 10:40:50 +00:00
2023-05-11 07:50:07 +00:00
var filter Filter
2023-05-28 10:40:50 +00:00
filter . Statuses = allActivityStatusesFilter ( )
2023-07-10 14:56:08 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
2023-05-28 10:40:50 +00:00
require . Equal ( t , 11 , len ( entries ) )
2023-05-11 07:50:07 +00:00
2023-05-28 10:40:50 +00:00
filter . Statuses = [ ] Status { PendingAS }
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
2023-05-28 10:40:50 +00:00
require . Equal ( t , 3 , len ( entries ) )
require . Equal ( t , td . pendingTr . Hash , entries [ 2 ] . transaction . Hash )
2023-06-14 16:10:20 +00:00
require . Equal ( t , td . multiTx2ID , entries [ 1 ] . id )
2023-05-28 10:40:50 +00:00
require . Equal ( t , trs [ 1 ] . Hash , entries [ 0 ] . transaction . Hash )
filter . Statuses = [ ] Status { FailedAS }
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-28 10:40:50 +00:00
require . NoError ( t , err )
require . Equal ( t , 2 , len ( entries ) )
filter . Statuses = [ ] Status { CompleteAS }
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-28 10:40:50 +00:00
require . NoError ( t , err )
require . Equal ( t , 6 , len ( entries ) )
// Finalized is treated as Complete, would need dynamic blockchain status to track the Finalized level
filter . Statuses = [ ] Status { FinalizedAS }
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-28 10:40:50 +00:00
require . NoError ( t , err )
require . Equal ( t , 6 , len ( entries ) )
2023-05-11 07:50:07 +00:00
2023-05-28 10:40:50 +00:00
// Combined filter
filter . Statuses = [ ] Status { FailedAS , PendingAS }
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-28 10:40:50 +00:00
require . NoError ( t , err )
require . Equal ( t , 5 , len ( entries ) )
2023-05-11 07:50:07 +00:00
}
func TestGetActivityEntriesFilterByTokenType ( t * testing . T ) {
2023-06-13 09:25:23 +00:00
deps , close := setupTestActivityDB ( t )
2023-05-11 07:50:07 +00:00
defer close ( )
2023-06-13 09:25:23 +00:00
// Adds 4 extractable transactions 2 transactions (ETH/Goerli, ETH/Optimism), one MT USDC to DAI and another MT USDC to SNT
td , fromTds , toTds := fillTestData ( t , deps . db )
// Add 9 transactions DAI/Goerli, ETH/Mainnet, ETH/Goerli, ETH/Optimism, USDC/Mainnet, USDC/Goerli, USDC/Optimism, SNT/Mainnet, DAI/Mainnet
trs , fromTrs , toTrs := transfer . GenerateTestTransfers ( t , deps . db , td . nextIndex , 9 )
2023-05-11 07:50:07 +00:00
for i := range trs {
2023-06-13 09:25:23 +00:00
tokenAddr := transfer . TestTokens [ i ] . Address
trs [ i ] . ChainID = common . ChainID ( transfer . TestTokens [ i ] . ChainID )
2023-06-27 22:49:02 +00:00
transfer . InsertTestTransferWithOptions ( t , deps . db , trs [ i ] . To , & trs [ i ] , & transfer . TestTransferOptions {
TokenAddress : tokenAddr ,
} )
2023-05-11 07:50:07 +00:00
}
2023-08-11 11:28:45 +00:00
mockTestAccountsWithAddresses ( t , deps . accountsDb , append ( append ( append ( fromTds , toTds ... ) , fromTrs ... ) , toTrs ... ) )
2023-05-28 10:40:50 +00:00
2023-05-11 07:50:07 +00:00
var filter Filter
2023-06-13 09:25:23 +00:00
filter . FilterOutAssets = true
2023-07-10 14:56:08 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
require . Equal ( t , 0 , len ( entries ) )
2023-06-13 09:25:23 +00:00
filter . FilterOutAssets = false
filter . Assets = allTokensFilter ( )
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
2023-06-13 09:25:23 +00:00
require . Equal ( t , 13 , len ( entries ) )
2023-05-11 07:50:07 +00:00
2023-06-13 09:25:23 +00:00
// Native tokens are network agnostic, hence all are returned
filter . Assets = [ ] Token { { TokenType : Native , ChainID : common . ChainID ( transfer . EthMainnet . ChainID ) } }
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
2023-06-13 09:25:23 +00:00
require . Equal ( t , 5 , len ( entries ) )
2023-05-11 07:50:07 +00:00
2023-06-13 09:25:23 +00:00
// Test that it doesn't break the filter
filter . Assets = [ ] Token { { TokenType : Erc1155 } }
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
2023-06-13 09:25:23 +00:00
require . Equal ( t , 0 , len ( entries ) )
2023-05-11 07:50:07 +00:00
2023-06-13 09:25:23 +00:00
filter . Assets = [ ] Token { {
TokenType : Erc20 ,
ChainID : common . ChainID ( transfer . UsdcMainnet . ChainID ) ,
Address : transfer . UsdcMainnet . Address ,
} }
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
2023-06-13 09:25:23 +00:00
// Two MT for which ChainID is ignored and one transfer on the main net and the Goerli is ignored
require . Equal ( t , 3 , len ( entries ) )
require . Equal ( t , Erc20 , entries [ 0 ] . tokenOut . TokenType )
require . Equal ( t , transfer . UsdcMainnet . Address , entries [ 0 ] . tokenOut . Address )
require . Nil ( t , entries [ 0 ] . tokenIn )
// MT has only symbol, the first token is lookup by symbol for both entries
require . Equal ( t , Erc20 , entries [ 1 ] . tokenOut . TokenType )
require . Equal ( t , transfer . UsdcMainnet . Address , entries [ 1 ] . tokenOut . Address )
require . Equal ( t , Erc20 , entries [ 1 ] . tokenIn . TokenType )
require . Equal ( t , transfer . SntMainnet . Address , entries [ 1 ] . tokenIn . Address )
require . Equal ( t , Erc20 , entries [ 2 ] . tokenOut . TokenType )
require . Equal ( t , transfer . UsdcMainnet . Address , entries [ 1 ] . tokenOut . Address )
require . Equal ( t , Erc20 , entries [ 2 ] . tokenIn . TokenType )
require . Equal ( t , transfer . UsdcMainnet . Address , entries [ 1 ] . tokenOut . Address )
filter . Assets = [ ] Token { {
TokenType : Erc20 ,
ChainID : common . ChainID ( transfer . UsdcMainnet . ChainID ) ,
Address : transfer . UsdcMainnet . Address ,
} , {
TokenType : Erc20 ,
ChainID : common . ChainID ( transfer . UsdcGoerli . ChainID ) ,
Address : transfer . UsdcGoerli . Address ,
} }
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-06-13 09:25:23 +00:00
require . NoError ( t , err )
// Two MT for which ChainID is ignored and two transfers on the main net and Goerli
require . Equal ( t , 4 , len ( entries ) )
require . Equal ( t , Erc20 , entries [ 0 ] . tokenOut . TokenType )
require . Equal ( t , transfer . UsdcGoerli . Address , entries [ 0 ] . tokenOut . Address )
require . Nil ( t , entries [ 0 ] . tokenIn )
2023-05-11 07:50:07 +00:00
}
func TestGetActivityEntriesFilterByToAddresses ( t * testing . T ) {
2023-06-13 09:25:23 +00:00
deps , close := setupTestActivityDB ( t )
2023-05-11 07:50:07 +00:00
defer close ( )
// Adds 4 extractable transactions
2023-06-13 09:25:23 +00:00
td , fromTds , toTds := fillTestData ( t , deps . db )
2023-05-11 07:50:07 +00:00
// Add 6 extractable transactions
2023-06-13 09:25:23 +00:00
trs , fromTrs , toTrs := transfer . GenerateTestTransfers ( t , deps . db , td . nextIndex , 6 )
2023-05-11 07:50:07 +00:00
for i := range trs {
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , deps . db , trs [ i ] . To , & trs [ i ] )
2023-05-11 07:50:07 +00:00
}
2023-08-11 11:28:45 +00:00
mockTestAccountsWithAddresses ( t , deps . accountsDb , append ( append ( append ( fromTds , toTds ... ) , fromTrs ... ) , toTrs ... ) )
2023-05-28 10:40:50 +00:00
2023-05-11 07:50:07 +00:00
var filter Filter
filter . CounterpartyAddresses = allAddressesFilter ( )
2023-07-10 14:56:08 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
require . Equal ( t , 10 , len ( entries ) )
2023-07-10 14:56:08 +00:00
filter . CounterpartyAddresses = [ ] eth . Address { eth . HexToAddress ( "0x567890" ) }
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
require . Equal ( t , 0 , len ( entries ) )
2023-07-10 14:56:08 +00:00
filter . CounterpartyAddresses = [ ] eth . Address { td . pendingTr . To , td . multiTx2 . ToAddress , trs [ 3 ] . To }
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
require . Equal ( t , 3 , len ( entries ) )
2023-07-10 14:56:08 +00:00
filter . CounterpartyAddresses = [ ] eth . Address { td . tr1 . To , td . pendingTr . From , trs [ 3 ] . From , trs [ 5 ] . To }
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
require . Equal ( t , 2 , len ( entries ) )
}
2023-07-25 16:03:33 +00:00
2023-05-11 07:50:07 +00:00
func TestGetActivityEntriesFilterByNetworks ( t * testing . T ) {
2023-06-13 09:25:23 +00:00
deps , close := setupTestActivityDB ( t )
2023-05-11 07:50:07 +00:00
defer close ( )
// Adds 4 extractable transactions
2023-06-13 09:25:23 +00:00
td , fromTds , toTds := fillTestData ( t , deps . db )
2023-07-25 16:03:33 +00:00
chainToEntryCount := make ( map [ common . ChainID ] map [ int ] int )
recordPresence := func ( chainID common . ChainID , entry int ) {
if _ , ok := chainToEntryCount [ chainID ] ; ! ok {
chainToEntryCount [ chainID ] = make ( map [ int ] int )
chainToEntryCount [ chainID ] [ entry ] = 1
} else {
if _ , ok := chainToEntryCount [ chainID ] [ entry ] ; ! ok {
chainToEntryCount [ chainID ] [ entry ] = 1
} else {
chainToEntryCount [ chainID ] [ entry ] ++
}
}
}
recordPresence ( td . tr1 . ChainID , 0 )
recordPresence ( td . pendingTr . ChainID , 1 )
recordPresence ( td . multiTx1Tr1 . ChainID , 2 )
if td . multiTx1Tr2 . ChainID != td . multiTx1Tr1 . ChainID {
recordPresence ( td . multiTx1Tr2 . ChainID , 2 )
}
recordPresence ( td . multiTx2Tr1 . ChainID , 3 )
if td . multiTx2Tr2 . ChainID != td . multiTx2Tr1 . ChainID {
recordPresence ( td . multiTx2Tr2 . ChainID , 3 )
}
if td . multiTx2PendingTr . ChainID != td . multiTx2Tr1 . ChainID && td . multiTx2PendingTr . ChainID != td . multiTx2Tr2 . ChainID {
recordPresence ( td . multiTx2PendingTr . ChainID , 3 )
}
2023-05-11 07:50:07 +00:00
// Add 6 extractable transactions
2023-06-13 09:25:23 +00:00
trs , fromTrs , toTrs := transfer . GenerateTestTransfers ( t , deps . db , td . nextIndex , 6 )
2023-05-11 07:50:07 +00:00
for i := range trs {
2023-07-25 16:03:33 +00:00
recordPresence ( trs [ i ] . ChainID , 4 + i )
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , deps . db , trs [ i ] . To , & trs [ i ] )
2023-05-11 07:50:07 +00:00
}
2023-08-11 11:28:45 +00:00
mockTestAccountsWithAddresses ( t , deps . accountsDb , append ( append ( append ( fromTds , toTds ... ) , fromTrs ... ) , toTrs ... ) )
2023-05-11 07:50:07 +00:00
var filter Filter
chainIDs := allNetworksFilter ( )
2023-07-10 14:56:08 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , chainIDs , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
require . Equal ( t , 10 , len ( entries ) )
chainIDs = [ ] common . ChainID { 5674839210 }
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , chainIDs , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
2023-07-25 16:03:33 +00:00
require . Equal ( t , 0 , len ( entries ) )
2023-05-11 07:50:07 +00:00
2023-06-14 16:10:20 +00:00
chainIDs = [ ] common . ChainID { td . pendingTr . ChainID , td . multiTx2Tr1 . ChainID , trs [ 3 ] . ChainID }
2023-07-10 14:56:08 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth . Address { } , chainIDs , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
2023-07-25 16:03:33 +00:00
expectedResults := make ( map [ int ] int )
for _ , chainID := range chainIDs {
for entry := range chainToEntryCount [ chainID ] {
if _ , ok := expectedResults [ entry ] ; ! ok {
expectedResults [ entry ] ++
}
}
}
require . Equal ( t , len ( expectedResults ) , len ( entries ) )
}
func TestGetActivityEntriesFilterByNetworksOfSubTransactions ( t * testing . T ) {
deps , close := setupTestActivityDB ( t )
defer close ( )
// Add 6 extractable transactions
trs , _ , toTrs := transfer . GenerateTestTransfers ( t , deps . db , 0 , 5 )
trs [ 0 ] . ChainID = 1231
trs [ 1 ] . ChainID = 1232
trs [ 2 ] . ChainID = 1233
mt1 := transfer . GenerateTestBridgeMultiTransaction ( trs [ 0 ] , trs [ 1 ] )
trs [ 0 ] . MultiTransactionID = transfer . InsertTestMultiTransaction ( t , deps . db , & mt1 )
trs [ 1 ] . MultiTransactionID = mt1 . MultiTransactionID
trs [ 2 ] . MultiTransactionID = mt1 . MultiTransactionID
trs [ 3 ] . ChainID = 1234
mt2 := transfer . GenerateTestSwapMultiTransaction ( trs [ 3 ] , testutils . SntSymbol , 100 )
2023-09-06 08:03:50 +00:00
// insertMultiTransaction will insert 0 instead of NULL
mt2 . FromNetworkID = common . NewAndSet ( uint64 ( 0 ) )
mt2 . ToNetworkID = common . NewAndSet ( uint64 ( 0 ) )
2023-07-25 16:03:33 +00:00
trs [ 3 ] . MultiTransactionID = transfer . InsertTestMultiTransaction ( t , deps . db , & mt2 )
for i := range trs {
if i == 2 {
transfer . InsertTestPendingTransaction ( t , deps . db , & trs [ i ] )
} else {
transfer . InsertTestTransfer ( t , deps . db , trs [ i ] . To , & trs [ i ] )
}
}
var filter Filter
chainIDs := allNetworksFilter ( )
entries , err := getActivityEntries ( context . Background ( ) , deps , toTrs , chainIDs , filter , 0 , 15 )
require . NoError ( t , err )
require . Equal ( t , 3 , len ( entries ) )
chainIDs = [ ] common . ChainID { trs [ 0 ] . ChainID , trs [ 1 ] . ChainID }
entries , err = getActivityEntries ( context . Background ( ) , deps , toTrs , chainIDs , filter , 0 , 15 )
require . NoError ( t , err )
require . Equal ( t , 1 , len ( entries ) )
require . Equal ( t , entries [ 0 ] . id , mt1 . MultiTransactionID )
2023-09-06 08:03:50 +00:00
// Filter by pending_transactions sub-transacitons
2023-07-25 16:03:33 +00:00
chainIDs = [ ] common . ChainID { trs [ 2 ] . ChainID }
entries , err = getActivityEntries ( context . Background ( ) , deps , toTrs , chainIDs , filter , 0 , 15 )
require . NoError ( t , err )
require . Equal ( t , 1 , len ( entries ) )
require . Equal ( t , entries [ 0 ] . id , mt1 . MultiTransactionID )
2023-09-06 08:03:50 +00:00
chainIDs = [ ] common . ChainID { trs [ 3 ] . ChainID }
entries , err = getActivityEntries ( context . Background ( ) , deps , toTrs , chainIDs , filter , 0 , 15 )
require . NoError ( t , err )
require . Equal ( t , 1 , len ( entries ) )
require . Equal ( t , entries [ 0 ] . id , mt2 . MultiTransactionID )
2023-05-11 07:50:07 +00:00
}
func TestGetActivityEntriesCheckToAndFrom ( t * testing . T ) {
2023-06-13 09:25:23 +00:00
deps , close := setupTestActivityDB ( t )
2023-05-11 07:50:07 +00:00
defer close ( )
2023-07-04 13:53:26 +00:00
// Adds 6 transactions from which 4 are filtered out
2023-06-13 09:25:23 +00:00
td , _ , _ := fillTestData ( t , deps . db )
2023-05-11 07:50:07 +00:00
// Add extra transactions to test To address
2023-06-13 09:25:23 +00:00
trs , _ , _ := transfer . GenerateTestTransfers ( t , deps . db , td . nextIndex , 2 )
2023-06-20 02:50:49 +00:00
transfer . InsertTestTransfer ( t , deps . db , trs [ 0 ] . To , & trs [ 0 ] )
2023-06-13 09:25:23 +00:00
transfer . InsertTestPendingTransaction ( t , deps . db , & trs [ 1 ] )
2023-05-11 07:50:07 +00:00
2023-07-10 14:56:08 +00:00
addresses := [ ] eth . Address { td . tr1 . From , td . pendingTr . From ,
2023-06-14 16:10:20 +00:00
td . multiTx1 . FromAddress , td . multiTx2 . ToAddress , trs [ 0 ] . To , trs [ 1 ] . To }
2023-05-11 07:50:07 +00:00
var filter Filter
2023-06-13 09:25:23 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , addresses , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
require . Equal ( t , 6 , len ( entries ) )
require . Equal ( t , SendAT , entries [ 5 ] . activityType ) // td.tr1
require . NotEqual ( t , eth . Address { } , entries [ 5 ] . transaction . Address ) // td.tr1
2023-07-25 16:03:33 +00:00
require . Equal ( t , td . tr1 . To , * entries [ 5 ] . recipient ) // td.tr1
2023-05-11 07:50:07 +00:00
require . Equal ( t , SendAT , entries [ 4 ] . activityType ) // td.pendingTr
// Multi-transactions are always considered as SendAT
2023-06-14 16:10:20 +00:00
require . Equal ( t , SendAT , entries [ 3 ] . activityType ) // td.multiTx1
require . Equal ( t , SendAT , entries [ 2 ] . activityType ) // td.multiTx2
2023-05-11 07:50:07 +00:00
require . Equal ( t , ReceiveAT , entries [ 1 ] . activityType ) // trs[0]
require . NotEqual ( t , eth . Address { } , entries [ 1 ] . transaction . Address ) // trs[0]
require . Equal ( t , trs [ 0 ] . To , entries [ 1 ] . transaction . Address ) // trs[0]
require . Equal ( t , ReceiveAT , entries [ 0 ] . activityType ) // trs[1] (pending)
// TODO: add accounts to DB for proper detection of sender/receiver
// TODO: Test with all addresses
}
2023-05-28 10:40:50 +00:00
2023-06-08 23:52:45 +00:00
func TestGetActivityEntriesCheckContextCancellation ( t * testing . T ) {
2023-06-13 09:25:23 +00:00
deps , close := setupTestActivityDB ( t )
2023-06-08 23:52:45 +00:00
defer close ( )
2023-06-13 09:25:23 +00:00
_ , _ , _ = fillTestData ( t , deps . db )
2023-06-08 23:52:45 +00:00
cancellableCtx , cancelFn := context . WithCancel ( context . Background ( ) )
cancelFn ( )
2023-06-13 09:25:23 +00:00
activities , err := getActivityEntries ( cancellableCtx , deps , [ ] eth . Address { } , [ ] common . ChainID { } , Filter { } , 0 , 10 )
2023-06-08 23:52:45 +00:00
require . ErrorIs ( t , err , context . Canceled )
require . Equal ( t , 0 , len ( activities ) )
}
2023-07-04 12:01:45 +00:00
func TestGetActivityEntriesNullAddresses ( t * testing . T ) {
deps , close := setupTestActivityDB ( t )
defer close ( )
trs , _ , _ := transfer . GenerateTestTransfers ( t , deps . db , 0 , 4 )
multiTx := transfer . GenerateTestBridgeMultiTransaction ( trs [ 0 ] , trs [ 1 ] )
2023-07-10 14:56:08 +00:00
multiTx . ToAddress = eth . Address { }
2023-07-04 12:01:45 +00:00
trs [ 0 ] . MultiTransactionID = transfer . InsertTestMultiTransaction ( t , deps . db , & multiTx )
trs [ 1 ] . MultiTransactionID = trs [ 0 ] . MultiTransactionID
for i := 0 ; i < 3 ; i ++ {
transfer . InsertTestTransferWithOptions ( t , deps . db , trs [ i ] . To , & trs [ i ] , & transfer . TestTransferOptions {
2023-07-10 14:56:08 +00:00
NullifyAddresses : [ ] eth . Address { trs [ i ] . To } ,
2023-07-04 12:01:45 +00:00
} )
}
2023-07-10 14:56:08 +00:00
trs [ 3 ] . To = eth . Address { }
2023-07-04 12:01:45 +00:00
transfer . InsertTestPendingTransaction ( t , deps . db , & trs [ 3 ] )
2023-08-11 11:28:45 +00:00
mockTestAccountsWithAddresses ( t , deps . accountsDb , [ ] eth . Address { trs [ 0 ] . From , trs [ 1 ] . From , trs [ 2 ] . From , trs [ 3 ] . From } )
2023-07-04 12:01:45 +00:00
activities , err := getActivityEntries ( context . Background ( ) , deps , allAddressesFilter ( ) , allNetworksFilter ( ) , Filter { } , 0 , 10 )
require . NoError ( t , err )
require . Equal ( t , 3 , len ( activities ) )
}
2023-07-10 15:00:35 +00:00
2023-08-24 12:23:40 +00:00
func TestGetTxDetails ( t * testing . T ) {
deps , close := setupTestActivityDB ( t )
defer close ( )
// Adds 4 extractable transactions 2 transactions (ETH/Goerli, ETH/Optimism), one MT USDC to DAI and another MT USDC to SNT
td , _ , _ := fillTestData ( t , deps . db )
_ , err := getTxDetails ( context . Background ( ) , deps . db , "" )
require . EqualError ( t , err , "invalid tx id" )
details , err := getTxDetails ( context . Background ( ) , deps . db , td . tr1 . Hash . String ( ) )
require . NoError ( t , err )
require . Equal ( t , td . tr1 . Hash . String ( ) , details . ID )
require . Equal ( t , 0 , details . MultiTxID )
require . Equal ( t , td . tr1 . Nonce , details . Nonce )
require . Equal ( t , td . tr1 . BlkNumber , details . BlockNumber )
require . Equal ( t , td . tr1 . Contract , * details . Contract )
}
func TestGetMultiTxDetails ( t * testing . T ) {
deps , close := setupTestActivityDB ( t )
defer close ( )
// Adds 4 extractable transactions 2 transactions (ETH/Goerli, ETH/Optimism), one MT USDC to DAI and another MT USDC to SNT
td , _ , _ := fillTestData ( t , deps . db )
_ , err := getMultiTxDetails ( context . Background ( ) , deps . db , 0 )
require . EqualError ( t , err , "invalid tx id" )
details , err := getMultiTxDetails ( context . Background ( ) , deps . db , int ( td . multiTx1 . MultiTransactionID ) )
require . NoError ( t , err )
require . Equal ( t , "" , details . ID )
require . Equal ( t , int ( td . multiTx1 . MultiTransactionID ) , details . MultiTxID )
require . Equal ( t , td . multiTx1Tr2 . Nonce , details . Nonce )
require . Equal ( t , td . multiTx1Tr2 . BlkNumber , details . BlockNumber )
require . Equal ( t , td . multiTx1Tr1 . Contract , * details . Contract )
}
2023-07-10 15:00:35 +00:00
func setupBenchmark ( b * testing . B , inMemory bool , resultCount int ) ( deps FilterDependencies , close func ( ) , accounts [ ] eth . Address ) {
deps , close = setupTestActivityDBStorageChoice ( b , inMemory )
const transactionCount = 100000
const mtSendRatio = 0.2 // 20%
const mtSwapRatio = 0.1 // 10%
const mtBridgeRatio = 0.1 // 10%
const pendingCount = 10
const mtSendCount = int ( float64 ( transactionCount ) * mtSendRatio )
const mtSwapCount = int ( float64 ( transactionCount ) * mtSwapRatio )
// Bridge requires two transactions
const mtBridgeCount = int ( float64 ( transactionCount ) * ( mtBridgeRatio / 2 ) )
trs , _ , _ := transfer . GenerateTestTransfers ( b , deps . db , 0 , transactionCount )
accounts = [ ] eth . Address { trs [ 0 ] . From , trs [ 1 ] . From , trs [ 2 ] . From , trs [ 3 ] . To , trs [ 4 ] . To , trs [ 5 ] . To }
i := 0
multiTxs := make ( [ ] transfer . TestMultiTransaction , mtSendCount + mtSwapCount + mtBridgeCount )
for ; i < mtSendCount ; i ++ {
multiTxs [ i ] = transfer . GenerateTestSendMultiTransaction ( trs [ i ] )
trs [ i ] . From = accounts [ i % len ( accounts ) ]
multiTxs [ i ] . FromAddress = trs [ i ] . From
multiTxs [ i ] . MultiTransactionID = transfer . InsertTestMultiTransaction ( b , deps . db , & multiTxs [ i ] )
trs [ i ] . MultiTransactionID = multiTxs [ i ] . MultiTransactionID
}
for j := 0 ; j < mtSwapCount ; i , j = i + 1 , j + 1 {
multiTxs [ i ] = transfer . GenerateTestSwapMultiTransaction ( trs [ i ] , testutils . SntSymbol , int64 ( i ) )
trs [ i ] . From = accounts [ i % len ( accounts ) ]
multiTxs [ i ] . FromAddress = trs [ i ] . From
multiTxs [ i ] . MultiTransactionID = transfer . InsertTestMultiTransaction ( b , deps . db , & multiTxs [ i ] )
trs [ i ] . MultiTransactionID = multiTxs [ i ] . MultiTransactionID
}
for mtIdx := 0 ; mtIdx < mtBridgeCount ; i , mtIdx = i + 2 , mtIdx + 1 {
firstTrIdx := i
secondTrIdx := i + 1
multiTxs [ mtIdx ] = transfer . GenerateTestBridgeMultiTransaction ( trs [ firstTrIdx ] , trs [ secondTrIdx ] )
trs [ firstTrIdx ] . From = accounts [ i % len ( accounts ) ]
trs [ secondTrIdx ] . To = accounts [ ( i + 3 ) % len ( accounts ) ]
multiTxs [ mtIdx ] . FromAddress = trs [ firstTrIdx ] . From
multiTxs [ mtIdx ] . ToAddress = trs [ secondTrIdx ] . To
multiTxs [ mtIdx ] . FromAddress = trs [ i ] . From
multiTxs [ mtIdx ] . MultiTransactionID = transfer . InsertTestMultiTransaction ( b , deps . db , & multiTxs [ mtIdx ] )
trs [ firstTrIdx ] . MultiTransactionID = multiTxs [ mtIdx ] . MultiTransactionID
trs [ secondTrIdx ] . MultiTransactionID = multiTxs [ mtIdx ] . MultiTransactionID
}
for i = 0 ; i < transactionCount - pendingCount ; i ++ {
trs [ i ] . From = accounts [ i % len ( accounts ) ]
transfer . InsertTestTransfer ( b , deps . db , trs [ i ] . To , & trs [ i ] )
}
for ; i < transactionCount ; i ++ {
trs [ i ] . From = accounts [ i % len ( accounts ) ]
transfer . InsertTestPendingTransaction ( b , deps . db , & trs [ i ] )
}
2023-08-11 11:28:45 +00:00
mockTestAccountsWithAddresses ( b , deps . accountsDb , accounts )
2023-07-10 15:00:35 +00:00
return
}
func BenchmarkGetActivityEntries ( bArg * testing . B ) {
type params struct {
inMemory bool
resultCount int
generateTestParameters func ( [ ] eth . Address ) ( addresses [ ] eth . Address , filter * Filter , startIndex int )
}
testCases := [ ] struct {
name string
params params
} {
{
"RAM_NoFilter" ,
params {
true ,
10 ,
func ( [ ] eth . Address ) ( [ ] eth . Address , * Filter , int ) {
return allAddressesFilter ( ) , & Filter { } , 0
} ,
} ,
} ,
{
"SSD_NoFilter" ,
params {
false ,
10 ,
func ( [ ] eth . Address ) ( [ ] eth . Address , * Filter , int ) {
return allAddressesFilter ( ) , & Filter { } , 0
} ,
} ,
} ,
{
"SSD_MovingWindow" ,
params {
false ,
10 ,
func ( addresses [ ] eth . Address ) ( [ ] eth . Address , * Filter , int ) {
return allAddressesFilter ( ) , & Filter { } , 200
} ,
} ,
} ,
{
"SSD_AllAddresses" ,
params {
false ,
10 ,
func ( addresses [ ] eth . Address ) ( [ ] eth . Address , * Filter , int ) {
return addresses , & Filter { } , 0
} ,
} ,
} ,
{
"SSD_AllAddresses_AllTos" ,
params {
false ,
10 ,
func ( addresses [ ] eth . Address ) ( [ ] eth . Address , * Filter , int ) {
return addresses , & Filter { CounterpartyAddresses : addresses [ 3 : ] } , 0
} ,
} ,
} ,
{
"SSD_OneAddress" ,
params {
false ,
10 ,
func ( addresses [ ] eth . Address ) ( [ ] eth . Address , * Filter , int ) {
return addresses [ 0 : 1 ] , & Filter { } , 0
} ,
} ,
} ,
}
deps , closeFn , accounts := setupBenchmark ( bArg , true , 10 )
defer closeFn ( )
const resultCount = 10
for _ , tc := range testCases {
addresses , filter , startIndex := tc . params . generateTestParameters ( accounts )
bArg . Run ( tc . name , func ( b * testing . B ) {
// Reset timer after setup
b . ResetTimer ( )
// Run benchmark
for i := 0 ; i < b . N ; i ++ {
res , err := getActivityEntries ( context . Background ( ) , deps , addresses , allNetworksFilter ( ) , * filter , startIndex , resultCount )
if err != nil || len ( res ) != resultCount {
b . Error ( err )
}
}
} )
}
}
2023-08-10 11:41:04 +00:00
func TestUpdateWalletKeypairsAccountsTable ( t * testing . T ) {
// initialize
appDb , err := helpers . SetupTestMemorySQLDB ( appdatabase . DbInitializer { } )
require . NoError ( t , err )
walletDb , err := helpers . SetupTestMemorySQLDB ( walletdatabase . DbInitializer { } )
require . NoError ( t , err )
accountsAppDb , err := accounts . NewDB ( appDb )
require . NoError ( t , err )
accountsWalletDb , err := accounts . NewDB ( walletDb )
require . NoError ( t , err )
// Check initially empty
addressesApp , err := accountsAppDb . GetWalletAddresses ( )
require . NoError ( t , err )
require . Empty ( t , addressesApp )
addressesWallet , err := accountsWalletDb . GetWalletAddresses ( )
require . Error ( t , err ) // no such table error
require . Empty ( t , addressesWallet )
// Insert 2 addresses in app db, but only 1 is a wallet
addresses := [ ] types . Address { { 0x01 } , { 0x02 } , { 0x03 } }
accounts := [ ] * accounts . Account {
{ Address : addresses [ 0 ] , Chat : true , Wallet : true } ,
{ Address : addresses [ 1 ] , Wallet : true } ,
{ Address : addresses [ 2 ] } ,
}
err = accountsAppDb . SaveOrUpdateAccounts ( accounts , false )
require . NoError ( t , err )
// Check only 2 wallet accs is returned in app db
addressesApp , err = accountsAppDb . GetWalletAddresses ( )
require . NoError ( t , err )
require . Len ( t , addressesApp , 2 )
// update wallet DB
err = updateKeypairsAccountsTable ( accountsAppDb , walletDb )
require . NoError ( t , err )
// Check only 2 wallet acc is returned in wallet db
var count int
err = walletDb . QueryRow ( fmt . Sprintf ( "SELECT count(address) FROM %s" , keypairAccountsTable ) ) . Scan ( & count )
require . NoError ( t , err )
require . Equal ( t , count , 2 )
// Compare addresses between app and wallet db
rows , err := walletDb . Query ( fmt . Sprintf ( "SELECT address FROM %s" , keypairAccountsTable ) )
require . NoError ( t , err )
for rows . Next ( ) {
var address types . Address
err = rows . Scan ( & address )
require . NoError ( t , err )
require . Contains ( t , addresses , address )
}
defer rows . Close ( )
}