Don't fail if one request fails in getTokensBalances

If one request failed, the whole batch would fail.
This caused issue as one of the contract is constantly returning an
error now, and essentially there was not way to fetch balance.
Also extend the timeout to 20s as we throw 165 request to Infura in one
go and it takes its time to reply to those, although it seems like we
should batch them on our side instead of sending them all cuncurrently.
This commit is contained in:
Andrea Maria Piana 2020-10-05 11:01:39 +02:00
parent 896f5c24bf
commit efbf093bc4
3 changed files with 13 additions and 5 deletions

View File

@ -1 +1 @@
0.62.7
0.62.8

View File

@ -10,10 +10,13 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/services/wallet/ierc20"
)
var requestTimeout = 20 * time.Second
// GetTokensBalances takes list of accounts and tokens and returns mapping of token balances for each account.
func GetTokensBalances(parent context.Context, client *ethclient.Client, accounts, tokens []common.Address) (map[common.Address]map[common.Address]*hexutil.Big, error) {
var (
@ -22,7 +25,7 @@ func GetTokensBalances(parent context.Context, client *ethclient.Client, account
response = map[common.Address]map[common.Address]*hexutil.Big{}
)
// requested current head to request balance on the same block number
ctx, cancel := context.WithTimeout(parent, 3*time.Second)
ctx, cancel := context.WithTimeout(parent, requestTimeout)
header, err := client.HeaderByNumber(ctx, nil)
cancel()
if err != nil {
@ -35,16 +38,21 @@ func GetTokensBalances(parent context.Context, client *ethclient.Client, account
return nil, err
}
for _, account := range accounts {
// Why we are doing this?
account := account
group.Add(func(parent context.Context) error {
ctx, cancel := context.WithTimeout(parent, 3*time.Second)
ctx, cancel := context.WithTimeout(parent, requestTimeout)
balance, err := caller.BalanceOf(&bind.CallOpts{
BlockNumber: header.Number,
Context: ctx,
}, account)
cancel()
// We don't want to return an error here and prevent
// the rest from completing
if err != nil {
return err
log.Error("can't fetch erc20 token balance", "account", account, "token", token, "error", err)
return nil
}
mu.Lock()
_, exist := response[account]

View File

@ -131,7 +131,7 @@ func (s *BalancesSuite) TestNoAccounts() {
func (s *BalancesSuite) TestTokenNotDeployed() {
_, err := GetTokensBalances(context.Background(), s.client, s.accounts, []common.Address{{0x01}})
s.Require().EqualError(err, "no contract code at given address")
s.Require().NoError(err)
}
func (s *BalancesSuite) TestInterrupted() {