github.com/status-im/status-go@v1.1.0/services/wallet/token/balance_persistence_test.go (about)

     1  package token
     2  
     3  import (
     4  	"math/big"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  
     9  	"github.com/status-im/status-go/rpc/network"
    10  	"github.com/status-im/status-go/services/wallet/community"
    11  	"github.com/status-im/status-go/t/helpers"
    12  	"github.com/status-im/status-go/walletdatabase"
    13  
    14  	"github.com/ethereum/go-ethereum/common"
    15  )
    16  
    17  func TestSaveTokens(t *testing.T) {
    18  	db, err := helpers.SetupTestMemorySQLDB(walletdatabase.DbInitializer{})
    19  
    20  	require.NoError(t, err)
    21  	require.NotNil(t, db)
    22  
    23  	persistence := NewPersistence(db)
    24  	require.NotNil(t, persistence)
    25  
    26  	tokens := make(map[common.Address][]StorageToken)
    27  	address1 := common.HexToAddress("0xdAC17F958D2ee523a2206206994597C13D831ec7")
    28  	address2 := common.HexToAddress("0x5e4e65926ba27467555eb562121fac00d24e9dd2")
    29  
    30  	tokenAddress1 := common.HexToAddress("0xDb8d79C775452a3929b86ac5DEaB3e9d38e1c006")
    31  	tokenAddress2 := common.HexToAddress("0xDb8d79C775452a3929b86ac5DEaB3e9d38e1c005")
    32  
    33  	var chain1 uint64 = 1
    34  	var chain2 uint64 = 2
    35  
    36  	token1 := StorageToken{
    37  		Token: Token{
    38  			Name:     "token-1",
    39  			Symbol:   "TT1",
    40  			Decimals: 10,
    41  		},
    42  		BalancesPerChain: make(map[uint64]ChainBalance),
    43  		Description:      "description-1",
    44  		AssetWebsiteURL:  "url-1",
    45  	}
    46  
    47  	token1.BalancesPerChain[chain1] = ChainBalance{
    48  		RawBalance: "1",
    49  		Balance:    big.NewFloat(0.1),
    50  		Address:    tokenAddress1,
    51  		ChainID:    chain1,
    52  	}
    53  
    54  	token1.BalancesPerChain[chain2] = ChainBalance{
    55  		RawBalance: "2",
    56  		Balance:    big.NewFloat(0.2),
    57  		Address:    tokenAddress2,
    58  		ChainID:    chain2,
    59  	}
    60  
    61  	token2 := StorageToken{
    62  		Token: Token{
    63  			Name:     "token-2",
    64  			Symbol:   "TT2",
    65  			Decimals: 11,
    66  		},
    67  		BalancesPerChain: make(map[uint64]ChainBalance),
    68  		Description:      "description-2",
    69  		AssetWebsiteURL:  "url-2",
    70  	}
    71  
    72  	token2.BalancesPerChain[chain1] = ChainBalance{
    73  		RawBalance: "3",
    74  		Balance:    big.NewFloat(0.3),
    75  		Address:    tokenAddress1,
    76  		ChainID:    chain1,
    77  	}
    78  
    79  	token3 := StorageToken{
    80  		Token: Token{
    81  			Name:     "token-3",
    82  			Symbol:   "TT3",
    83  			Decimals: 11,
    84  		},
    85  		BalancesPerChain: make(map[uint64]ChainBalance),
    86  		Description:      "description-3",
    87  		AssetWebsiteURL:  "url-3",
    88  	}
    89  
    90  	token3.BalancesPerChain[chain1] = ChainBalance{
    91  		RawBalance: "4",
    92  		Balance:    big.NewFloat(0.4),
    93  		Address:    tokenAddress1,
    94  		ChainID:    chain1,
    95  	}
    96  
    97  	tokens[address1] = []StorageToken{token1, token2}
    98  
    99  	tokens[address2] = []StorageToken{token3}
   100  
   101  	require.NoError(t, persistence.SaveTokens(tokens))
   102  
   103  	actualTokens, err := persistence.GetTokens()
   104  	require.NoError(t, err)
   105  	require.NotNil(t, actualTokens)
   106  	require.NotNil(t, actualTokens[address1])
   107  	require.Len(t, actualTokens[address1], 2)
   108  
   109  	var actualToken1, actualToken2, actualToken3 StorageToken
   110  	if actualTokens[address1][0].Name == "token-1" {
   111  		actualToken1 = actualTokens[address1][0]
   112  		actualToken2 = actualTokens[address1][1]
   113  	} else {
   114  		actualToken1 = actualTokens[address1][1]
   115  		actualToken2 = actualTokens[address1][0]
   116  
   117  	}
   118  
   119  	require.NotNil(t, actualTokens[address2])
   120  	require.Len(t, actualTokens[address2], 1)
   121  
   122  	actualToken3 = actualTokens[address2][0]
   123  
   124  	require.Equal(t, actualToken1.Name, token1.Name)
   125  	require.Equal(t, actualToken1.Symbol, token1.Symbol)
   126  	require.Equal(t, actualToken1.Decimals, token1.Decimals)
   127  	require.Equal(t, actualToken1.Description, token1.Description)
   128  	require.Equal(t, actualToken1.AssetWebsiteURL, token1.AssetWebsiteURL)
   129  
   130  	require.Equal(t, actualToken1.BalancesPerChain[chain1].RawBalance, "1")
   131  	require.NotNil(t, actualToken1.BalancesPerChain[chain1].Balance)
   132  	require.Equal(t, actualToken1.BalancesPerChain[chain1].Balance.String(), "0.1")
   133  	require.Equal(t, actualToken1.BalancesPerChain[chain1].Address, tokenAddress1)
   134  	require.Equal(t, actualToken1.BalancesPerChain[chain1].ChainID, chain1)
   135  
   136  	require.Equal(t, actualToken1.BalancesPerChain[chain2].RawBalance, "2")
   137  	require.NotNil(t, actualToken1.BalancesPerChain[chain2].Balance)
   138  	require.Equal(t, actualToken1.BalancesPerChain[chain2].Balance.String(), "0.2")
   139  	require.Equal(t, actualToken1.BalancesPerChain[chain2].Address, tokenAddress2)
   140  	require.Equal(t, actualToken1.BalancesPerChain[chain2].ChainID, chain2)
   141  
   142  	require.Equal(t, actualToken2.Name, token2.Name)
   143  	require.Equal(t, actualToken2.Symbol, token2.Symbol)
   144  	require.Equal(t, actualToken2.Decimals, token2.Decimals)
   145  	require.Equal(t, actualToken2.Description, token2.Description)
   146  	require.Equal(t, actualToken2.AssetWebsiteURL, token2.AssetWebsiteURL)
   147  
   148  	require.Equal(t, actualToken2.BalancesPerChain[chain1].RawBalance, "3")
   149  	require.NotNil(t, actualToken2.BalancesPerChain[chain1].Balance)
   150  	require.Equal(t, actualToken2.BalancesPerChain[chain1].Balance.String(), "0.3")
   151  	require.Equal(t, actualToken2.BalancesPerChain[chain1].Address, tokenAddress1)
   152  	require.Equal(t, actualToken2.BalancesPerChain[chain1].ChainID, chain1)
   153  
   154  	require.Equal(t, actualToken3.Name, token3.Name)
   155  	require.Equal(t, actualToken3.Symbol, token3.Symbol)
   156  	require.Equal(t, actualToken3.Decimals, token3.Decimals)
   157  	require.Equal(t, actualToken3.Description, token3.Description)
   158  	require.Equal(t, actualToken3.AssetWebsiteURL, token3.AssetWebsiteURL)
   159  
   160  	require.Equal(t, actualToken3.BalancesPerChain[chain1].RawBalance, "4")
   161  	require.NotNil(t, actualToken3.BalancesPerChain[chain1].Balance)
   162  	require.Equal(t, actualToken3.BalancesPerChain[chain1].Balance.String(), "0.4")
   163  	require.Equal(t, actualToken3.BalancesPerChain[chain1].Address, tokenAddress1)
   164  	require.Equal(t, actualToken3.BalancesPerChain[chain1].ChainID, chain1)
   165  }
   166  
   167  func TestGetCachedBalancesByChain(t *testing.T) {
   168  	db, err := helpers.SetupTestMemorySQLDB(walletdatabase.DbInitializer{})
   169  
   170  	require.NoError(t, err)
   171  	require.NotNil(t, db)
   172  
   173  	persistence := NewPersistence(db)
   174  	require.NotNil(t, persistence)
   175  
   176  	tokens := make(map[common.Address][]StorageToken)
   177  	address1 := common.HexToAddress("0xdAC17F958D2ee523a2206206994597C13D831ec7")
   178  	address2 := common.HexToAddress("0x5e4e65926ba27467555eb562121fac00d24e9dd2")
   179  
   180  	tokenAddress1 := common.HexToAddress("0xDb8d79C775452a3929b86ac5DEaB3e9d38e1c006")
   181  	tokenAddress2 := common.HexToAddress("0xDb8d79C775452a3929b86ac5DEaB3e9d38e1c005")
   182  
   183  	var chain1 uint64 = 1
   184  	var chain2 uint64 = 2
   185  
   186  	token1 := StorageToken{
   187  		Token: Token{
   188  			Name:     "token-1",
   189  			Symbol:   "TT1",
   190  			Decimals: 18,
   191  		},
   192  		BalancesPerChain: make(map[uint64]ChainBalance),
   193  		Description:      "description-1",
   194  		AssetWebsiteURL:  "url-1",
   195  	}
   196  
   197  	token1.BalancesPerChain[chain1] = ChainBalance{
   198  		RawBalance: "1",
   199  		// min eth number (not zero)
   200  		Balance: big.NewFloat(0.000000000000000001),
   201  		Address: tokenAddress1,
   202  		ChainID: chain1,
   203  	}
   204  
   205  	token2 := StorageToken{
   206  		Token: Token{
   207  			Name:     "token-2",
   208  			Symbol:   "TT2",
   209  			Decimals: 10,
   210  		},
   211  		BalancesPerChain: make(map[uint64]ChainBalance),
   212  		Description:      "description-2",
   213  		AssetWebsiteURL:  "url-2",
   214  	}
   215  
   216  	token2.BalancesPerChain[chain2] = ChainBalance{
   217  		RawBalance: "1000000000000000000",
   218  		Balance:    big.NewFloat(1),
   219  		Address:    tokenAddress2,
   220  		ChainID:    chain1,
   221  	}
   222  
   223  	tokens[address1] = []StorageToken{token1}
   224  	tokens[address2] = []StorageToken{token2}
   225  
   226  	require.NoError(t, persistence.SaveTokens(tokens))
   227  
   228  	tokenManager := NewTokenManager(db, nil, community.NewManager(db, nil, nil), network.NewManager(db), db, nil, nil, nil, nil, persistence)
   229  
   230  	// Verify that the token balance was inserted correctly
   231  	var count int
   232  	err = db.QueryRow(`SELECT count(*) FROM token_balances`).Scan(&count)
   233  	require.NoError(t, err)
   234  	require.Equal(t, 2, count)
   235  
   236  	nonExistingAddress := common.HexToAddress("0xaAC17F958D2ee523a2206206994597C13D831ec8")
   237  	result, err := tokenManager.GetCachedBalancesByChain([]common.Address{nonExistingAddress}, []common.Address{tokenAddress1}, []uint64{chain1})
   238  	require.NoError(t, err)
   239  	require.Len(t, result, 0)
   240  
   241  	result, err = tokenManager.GetCachedBalancesByChain([]common.Address{address1}, []common.Address{tokenAddress1}, []uint64{chain1})
   242  	require.NoError(t, err)
   243  	require.Len(t, result, 1)
   244  
   245  	require.Equal(t, result[chain1][address1][tokenAddress1].ToInt(), big.NewInt(1))
   246  
   247  	result, err = tokenManager.GetCachedBalancesByChain([]common.Address{address1, address2}, []common.Address{tokenAddress2, tokenAddress1}, []uint64{chain1, chain2})
   248  	require.NoError(t, err)
   249  	require.Len(t, result, 2)
   250  
   251  	require.Equal(t, result[chain1][address1][tokenAddress1].ToInt(), big.NewInt(1))
   252  	require.Equal(t, result[chain2][address2][tokenAddress2].ToInt(), big.NewInt(1000000000000000000))
   253  }