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-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-05-11 07:50:07 +00:00
eth "github.com/ethereum/go-ethereum/common"
eth_common "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
}
func setupTestActivityDB ( t * testing . T ) ( deps FilterDependencies , close func ( ) ) {
2023-04-21 11:59:29 +00:00
db , err := appdatabase . SetupTestMemorySQLDB ( "wallet-activity-tests" )
require . NoError ( t , err )
2023-06-13 09:25:23 +00:00
deps = FilterDependencies {
db : db ,
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-04-21 11:59:29 +00:00
require . NoError ( t , db . Close ( ) )
}
}
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-05-28 10:40:50 +00:00
func mockTestAccountsWithAddresses ( t * testing . T , db * sql . DB , addresses [ ] eth_common . Address ) {
mockedAccounts := [ ] * accounts . Account { }
for _ , address := range addresses {
mockedAccounts = append ( mockedAccounts , & accounts . Account {
Address : types . Address ( address ) ,
Type : accounts . AccountTypeWatch ,
} )
}
accounts . MockTestAccounts ( t , db , mockedAccounts )
}
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-05-28 10:40:50 +00:00
func fillTestData ( t * testing . T , db * sql . DB ) ( td testData , fromAddresses , toAddresses [ ] eth_common . 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 ]
2023-06-13 09:25:23 +00:00
// TODO: This got automatically set by GenerateTestTransfers to USDC/Mainnet
//td.multiTx1Tr1.Token = &transfer.SntMainnet
2023-06-14 16:10:20 +00:00
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-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 ,
} , 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 ,
} , 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 ) ,
} , 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 ) ,
} , 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-06-13 09:25:23 +00:00
mockTestAccountsWithAddresses ( t , deps . db , 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-04 22:21:07 +00:00
// TODO: extract and use to/from Address to compare instead of identity
require . Equal ( t , td . tr1 . To , entries [ 0 ] . transaction . Address )
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-06-13 09:25:23 +00:00
mockTestAccountsWithAddresses ( t , deps . db , 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-06-13 09:25:23 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 8 , 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 [ 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-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-04-21 11:59:29 +00:00
} , entries [ 7 ] )
// Test complete interval
filter . Period . EndTimestamp = trs [ 2 ] . Timestamp
2023-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-04-21 11:59:29 +00:00
require . NoError ( t , err )
require . Equal ( t , 5 , 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-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-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-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-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-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-06-13 09:25:23 +00:00
mockTestAccountsWithAddresses ( t , deps . db , 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-06-13 09:25:23 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-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-04-21 11:59:29 +00:00
} , entries [ 2 ] )
// Move window 2 entries forward
2023-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-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-04-21 11:59:29 +00:00
} , entries [ 2 ] )
// Move window 4 more entries to test filter cap
2023-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-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-06-14 16:10:20 +00:00
addresses := [ ] eth_common . 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-06-13 09:25:23 +00:00
mockTestAccountsWithAddresses ( t , deps . db , 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-06-14 16:10:20 +00:00
addressesFilter = [ ] eth_common . 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-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-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-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-06-13 09:25:23 +00:00
mockTestAccountsWithAddresses ( t , deps . db , 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-06-13 09:25:23 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-06-13 09:25:23 +00:00
mockTestAccountsWithAddresses ( t , deps . db , 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
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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 ( )
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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 ) } }
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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 } }
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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 ,
} }
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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 ,
} }
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
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-06-13 09:25:23 +00:00
mockTestAccountsWithAddresses ( t , deps . db , 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-06-13 09:25:23 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
require . Equal ( t , 10 , len ( entries ) )
filter . CounterpartyAddresses = [ ] eth_common . Address { eth_common . HexToAddress ( "0x567890" ) }
2023-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-14 16:10:20 +00:00
filter . CounterpartyAddresses = [ ] eth_common . Address { td . pendingTr . To , td . multiTx2 . ToAddress , trs [ 3 ] . To }
2023-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
require . Equal ( t , 3 , len ( entries ) )
filter . CounterpartyAddresses = [ ] eth_common . Address { td . tr1 . To , td . pendingTr . From , trs [ 3 ] . From , trs [ 5 ] . To }
2023-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . Address { } , [ ] common . ChainID { } , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
require . Equal ( t , 2 , len ( entries ) )
}
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-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-06-13 09:25:23 +00:00
mockTestAccountsWithAddresses ( t , deps . db , append ( append ( append ( fromTds , toTds ... ) , fromTrs ... ) , toTrs ... ) )
2023-05-11 07:50:07 +00:00
var filter Filter
chainIDs := allNetworksFilter ( )
2023-06-13 09:25:23 +00:00
entries , err := getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . 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-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . Address { } , chainIDs , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
// TODO: update after multi-transactions are filterable by ChainID
require . Equal ( t , 2 /*0*/ , len ( entries ) )
2023-06-14 16:10:20 +00:00
chainIDs = [ ] common . ChainID { td . pendingTr . ChainID , td . multiTx2Tr1 . ChainID , trs [ 3 ] . ChainID }
2023-06-13 09:25:23 +00:00
entries , err = getActivityEntries ( context . Background ( ) , deps , [ ] eth_common . Address { } , chainIDs , filter , 0 , 15 )
2023-05-11 07:50:07 +00:00
require . NoError ( t , err )
// TODO: update after multi-transactions are filterable by ChainID
2023-06-13 09:25:23 +00:00
require . Equal ( t , 8 /*6*/ , len ( entries ) )
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
addresses := [ ] eth_common . 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-04 22:21:07 +00:00
// TODO: extract to/from Address and use it for comparison instead of identity address
require . Equal ( t , td . tr1 . To , entries [ 5 ] . transaction . Address ) // 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
// TODO test sub-transaction count for multi-transactions
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 ( )
// Add 6 extractable transactions
trs , _ , _ := transfer . GenerateTestTransfers ( t , deps . db , 0 , 4 )
multiTx := transfer . GenerateTestBridgeMultiTransaction ( trs [ 0 ] , trs [ 1 ] )
multiTx . ToAddress = eth_common . Address { }
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 {
NullifyAddresses : [ ] eth_common . Address { trs [ i ] . To } ,
} )
}
trs [ 3 ] . To = eth_common . Address { }
transfer . InsertTestPendingTransaction ( t , deps . db , & trs [ 3 ] )
mockTestAccountsWithAddresses ( t , deps . db , [ ] eth_common . Address { trs [ 0 ] . From , trs [ 1 ] . From , trs [ 2 ] . From , trs [ 3 ] . From } )
activities , err := getActivityEntries ( context . Background ( ) , deps , allAddressesFilter ( ) , allNetworksFilter ( ) , Filter { } , 0 , 10 )
require . NoError ( t , err )
require . Equal ( t , 3 , len ( activities ) )
}