We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Etherscan balance query for more than 20 accounts won't work
Etherscan has a 20 account limit per query.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `rotkehlchen/ethchain.py`
Content:
```
1 import os
2 from web3 import Web3, HTTPProvider
3 from requests import ConnectionError
4 
5 from rotkehlchen.utils import from_wei, rlk_jsonloads, request_get
6 from rotkehlchen.fval import FVal
7 
8 import logging
9 logger = logging.getLogger(__name__)
10 
11 
12 class Ethchain(object):
13     def __init__(self, ethrpc_port, attempt_connect=True):
14         self.web3 = None
15         self.rpc_port = ethrpc_port
16         self.connected = False
17         if attempt_connect:
18             self.attempt_connect(ethrpc_port)
19 
20     def attempt_connect(self, ethrpc_port, mainnet_check=True):
21         if self.rpc_port == ethrpc_port and self.connected:
22             # We are already connected
23             return True, 'Already connected to an ethereum node'
24 
25         if self.web3:
26             del self.web3
27 
28         try:
29             self.web3 = Web3(HTTPProvider('http://localhost:{}'.format(ethrpc_port)))
30         except ConnectionError:
31             logger.warn('Could not connect to a local ethereum node. Will use etherscan only')
32             self.connected = False
33             return False, 'Failed to connect to ethereum node at port {}'.format(ethrpc_port)
34 
35         if self.web3.isConnected():
36             dir_path = os.path.dirname(os.path.realpath(__file__))
37             with open(os.path.join(dir_path, 'data', 'token_abi.json'), 'r') as f:
38                 self.token_abi = rlk_jsonloads(f.read())
39 
40             # Also make sure we are actually connected to the Ethereum mainnet
41             if mainnet_check:
42                 genesis_hash = self.web3.eth.getBlock(0)['hash'].hex()
43                 target = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3'
44                 if genesis_hash != target:
45                     logger.warn(
46                         'Connected to a local ethereum node but it is not on the ethereum mainnet'
47                     )
48                     self.connected = False
49                     message = (
50                         'Connected to ethereum node at port {} but it is not on '
51                         'the ethereum mainnet'.format(ethrpc_port)
52                     )
53                     return False, message
54 
55             self.connected = True
56             return True, ''
57         else:
58             logger.warn('Could not connect to a local ethereum node. Will use etherscan only')
59             self.connected = False
60             message = 'Failed to connect to ethereum node at port {}'.format(ethrpc_port)
61 
62         # If we get here we did not connnect
63         return False, message
64 
65     def set_rpc_port(self, port):
66         """ Attempts to set the RPC port for the ethereum client.
67 
68         Returns a tuple (result, message)
69             - result: Boolean for success or failure of changing the rpc port
70             - message: A message containing information on what happened. Can
71                        be populated both in case of success or failure"""
72         result, message = self.attempt_connect(port)
73         if result:
74             self.ethrpc_port = port
75         return result, message
76 
77     def get_eth_balance(self, account):
78         if not self.connected:
79             eth_resp = request_get(
80                 'https://api.etherscan.io/api?module=account&action=balance&address=%s'
81                 % account
82             )
83             if eth_resp['status'] != 1:
84                 raise ValueError('Failed to query etherscan for accounts balance')
85             amount = FVal(eth_resp['result'])
86             return from_wei(amount)
87         else:
88             return from_wei(self.web3.eth.getBalance(account))
89 
90     def get_multieth_balance(self, accounts):
91         """Returns a dict with keys being accounts and balances in ETH"""
92         balances = {}
93         if not self.connected:
94             # TODO: accounts.length should be less than 20. If more we gotta do
95             # multiple calls
96             eth_resp = request_get(
97                 'https://api.etherscan.io/api?module=account&action=balancemulti&address=%s' %
98                 ','.join(accounts)
99             )
100             if eth_resp['status'] != 1:
101                 raise ValueError('Failed to query etherscan for accounts balance')
102             eth_accounts = eth_resp['result']
103             for account_entry in eth_accounts:
104                 amount = FVal(account_entry['balance'])
105                 balances[account_entry['account']] = from_wei(amount)
106 
107         else:
108             for account in accounts:
109                 amount = FVal(self.web3.eth.getBalance(account))
110                 balances[account] = from_wei(amount)
111 
112         return balances
113 
114     def get_multitoken_balance(self, token_symbol, token_address, token_decimals, accounts):
115         """Return a dictionary with keys being accounts and value balances of token
116         Balance value is normalized through the token decimals.
117         """
118         balances = {}
119         if self.connected:
120             token_contract = self.web3.eth.contract(
121                 address=token_address,
122                 abi=self.token_abi
123             )
124             for account in accounts:
125                 token_amount = FVal(token_contract.functions.balanceOf(account).call())
126                 if token_amount != 0:
127                     balances[account] = token_amount / (FVal(10) ** FVal(token_decimals))
128         else:
129             for account in accounts:
130                 print('Checking token {} for account {}'.format(token_symbol, account))
131                 resp = request_get(
132                     'https://api.etherscan.io/api?module=account&action='
133                     'tokenbalance&contractaddress={}&address={}'.format(
134                         token_address,
135                         account,
136                     ))
137                 if resp['status'] != 1:
138                     raise ValueError(
139                         'Failed to query etherscan for {} token balance of {}'.format(
140                             token_symbol,
141                             account,
142                         ))
143                 token_amount = FVal(resp['result'])
144                 if token_amount != 0:
145                     balances[account] = token_amount / (FVal(10) ** FVal(token_decimals))
146 
147         return balances
148 
149     def get_token_balance(self, token_symbol, token_address, token_decimals, account):
150         res = self.get_multitoken_balance(token_symbol, token_address, token_decimals, [account])
151         return res.get(account, 0)
152 
153     def get_block_by_number(self, num):
154         if not self.connected:
155             return None
156 
157         return self.web3.eth.getBlock(num)
158
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/rotkehlchen/ethchain.py b/rotkehlchen/ethchain.py
--- a/rotkehlchen/ethchain.py
+++ b/rotkehlchen/ethchain.py
@@ -90,19 +90,25 @@
     def get_multieth_balance(self, accounts):
         """Returns a dict with keys being accounts and balances in ETH"""
         balances = {}
+
         if not self.connected:
-            # TODO: accounts.length should be less than 20. If more we gotta do
-            # multiple calls
-            eth_resp = request_get(
-                'https://api.etherscan.io/api?module=account&action=balancemulti&address=%s' %
-                ','.join(accounts)
-            )
-            if eth_resp['status'] != 1:
-                raise ValueError('Failed to query etherscan for accounts balance')
-            eth_accounts = eth_resp['result']
-            for account_entry in eth_accounts:
-                amount = FVal(account_entry['balance'])
-                balances[account_entry['account']] = from_wei(amount)
+            if len(accounts) > 20:
+                new_accounts = [accounts[x:x+2] for x in range(0, len(accounts), 2)]
+            else:
+                new_accounts = [accounts]
+
+            for account_slice in new_accounts:
+                eth_resp = request_get(
+                    'https://api.etherscan.io/api?module=account&action=balancemulti&address=%s' %
+                    ','.join(account_slice)
+                )
+                if eth_resp['status'] != 1:
+                    raise ValueError('Failed to query etherscan for accounts balance')
+                eth_accounts = eth_resp['result']
+
+                for account_entry in eth_accounts:
+                    amount = FVal(account_entry['balance'])
+                    balances[account_entry['account']] = from_wei(amount)
 
         else:
             for account in accounts:

{"golden_diff": "diff --git a/rotkehlchen/ethchain.py b/rotkehlchen/ethchain.py\n--- a/rotkehlchen/ethchain.py\n+++ b/rotkehlchen/ethchain.py\n@@ -90,19 +90,25 @@\n     def get_multieth_balance(self, accounts):\n         \"\"\"Returns a dict with keys being accounts and balances in ETH\"\"\"\n         balances = {}\n+\n         if not self.connected:\n-            # TODO: accounts.length should be less than 20. If more we gotta do\n-            # multiple calls\n-            eth_resp = request_get(\n-                'https://api.etherscan.io/api?module=account&action=balancemulti&address=%s' %\n-                ','.join(accounts)\n-            )\n-            if eth_resp['status'] != 1:\n-                raise ValueError('Failed to query etherscan for accounts balance')\n-            eth_accounts = eth_resp['result']\n-            for account_entry in eth_accounts:\n-                amount = FVal(account_entry['balance'])\n-                balances[account_entry['account']] = from_wei(amount)\n+            if len(accounts) > 20:\n+                new_accounts = [accounts[x:x+2] for x in range(0, len(accounts), 2)]\n+            else:\n+                new_accounts = [accounts]\n+\n+            for account_slice in new_accounts:\n+                eth_resp = request_get(\n+                    'https://api.etherscan.io/api?module=account&action=balancemulti&address=%s' %\n+                    ','.join(account_slice)\n+                )\n+                if eth_resp['status'] != 1:\n+                    raise ValueError('Failed to query etherscan for accounts balance')\n+                eth_accounts = eth_resp['result']\n+\n+                for account_entry in eth_accounts:\n+                    amount = FVal(account_entry['balance'])\n+                    balances[account_entry['account']] = from_wei(amount)\n \n         else:\n             for account in accounts:\n", "issue": "Etherscan balance query for more than 20 accounts won't work\nEtherscan has a 20 account limit per query.\n", "before_files": [{"content": "import os\nfrom web3 import Web3, HTTPProvider\nfrom requests import ConnectionError\n\nfrom rotkehlchen.utils import from_wei, rlk_jsonloads, request_get\nfrom rotkehlchen.fval import FVal\n\nimport logging\nlogger = logging.getLogger(__name__)\n\n\nclass Ethchain(object):\n    def __init__(self, ethrpc_port, attempt_connect=True):\n        self.web3 = None\n        self.rpc_port = ethrpc_port\n        self.connected = False\n        if attempt_connect:\n            self.attempt_connect(ethrpc_port)\n\n    def attempt_connect(self, ethrpc_port, mainnet_check=True):\n        if self.rpc_port == ethrpc_port and self.connected:\n            # We are already connected\n            return True, 'Already connected to an ethereum node'\n\n        if self.web3:\n            del self.web3\n\n        try:\n            self.web3 = Web3(HTTPProvider('http://localhost:{}'.format(ethrpc_port)))\n        except ConnectionError:\n            logger.warn('Could not connect to a local ethereum node. Will use etherscan only')\n            self.connected = False\n            return False, 'Failed to connect to ethereum node at port {}'.format(ethrpc_port)\n\n        if self.web3.isConnected():\n            dir_path = os.path.dirname(os.path.realpath(__file__))\n            with open(os.path.join(dir_path, 'data', 'token_abi.json'), 'r') as f:\n                self.token_abi = rlk_jsonloads(f.read())\n\n            # Also make sure we are actually connected to the Ethereum mainnet\n            if mainnet_check:\n                genesis_hash = self.web3.eth.getBlock(0)['hash'].hex()\n                target = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3'\n                if genesis_hash != target:\n                    logger.warn(\n                        'Connected to a local ethereum node but it is not on the ethereum mainnet'\n                    )\n                    self.connected = False\n                    message = (\n                        'Connected to ethereum node at port {} but it is not on '\n                        'the ethereum mainnet'.format(ethrpc_port)\n                    )\n                    return False, message\n\n            self.connected = True\n            return True, ''\n        else:\n            logger.warn('Could not connect to a local ethereum node. Will use etherscan only')\n            self.connected = False\n            message = 'Failed to connect to ethereum node at port {}'.format(ethrpc_port)\n\n        # If we get here we did not connnect\n        return False, message\n\n    def set_rpc_port(self, port):\n        \"\"\" Attempts to set the RPC port for the ethereum client.\n\n        Returns a tuple (result, message)\n            - result: Boolean for success or failure of changing the rpc port\n            - message: A message containing information on what happened. Can\n                       be populated both in case of success or failure\"\"\"\n        result, message = self.attempt_connect(port)\n        if result:\n            self.ethrpc_port = port\n        return result, message\n\n    def get_eth_balance(self, account):\n        if not self.connected:\n            eth_resp = request_get(\n                'https://api.etherscan.io/api?module=account&action=balance&address=%s'\n                % account\n            )\n            if eth_resp['status'] != 1:\n                raise ValueError('Failed to query etherscan for accounts balance')\n            amount = FVal(eth_resp['result'])\n            return from_wei(amount)\n        else:\n            return from_wei(self.web3.eth.getBalance(account))\n\n    def get_multieth_balance(self, accounts):\n        \"\"\"Returns a dict with keys being accounts and balances in ETH\"\"\"\n        balances = {}\n        if not self.connected:\n            # TODO: accounts.length should be less than 20. If more we gotta do\n            # multiple calls\n            eth_resp = request_get(\n                'https://api.etherscan.io/api?module=account&action=balancemulti&address=%s' %\n                ','.join(accounts)\n            )\n            if eth_resp['status'] != 1:\n                raise ValueError('Failed to query etherscan for accounts balance')\n            eth_accounts = eth_resp['result']\n            for account_entry in eth_accounts:\n                amount = FVal(account_entry['balance'])\n                balances[account_entry['account']] = from_wei(amount)\n\n        else:\n            for account in accounts:\n                amount = FVal(self.web3.eth.getBalance(account))\n                balances[account] = from_wei(amount)\n\n        return balances\n\n    def get_multitoken_balance(self, token_symbol, token_address, token_decimals, accounts):\n        \"\"\"Return a dictionary with keys being accounts and value balances of token\n        Balance value is normalized through the token decimals.\n        \"\"\"\n        balances = {}\n        if self.connected:\n            token_contract = self.web3.eth.contract(\n                address=token_address,\n                abi=self.token_abi\n            )\n            for account in accounts:\n                token_amount = FVal(token_contract.functions.balanceOf(account).call())\n                if token_amount != 0:\n                    balances[account] = token_amount / (FVal(10) ** FVal(token_decimals))\n        else:\n            for account in accounts:\n                print('Checking token {} for account {}'.format(token_symbol, account))\n                resp = request_get(\n                    'https://api.etherscan.io/api?module=account&action='\n                    'tokenbalance&contractaddress={}&address={}'.format(\n                        token_address,\n                        account,\n                    ))\n                if resp['status'] != 1:\n                    raise ValueError(\n                        'Failed to query etherscan for {} token balance of {}'.format(\n                            token_symbol,\n                            account,\n                        ))\n                token_amount = FVal(resp['result'])\n                if token_amount != 0:\n                    balances[account] = token_amount / (FVal(10) ** FVal(token_decimals))\n\n        return balances\n\n    def get_token_balance(self, token_symbol, token_address, token_decimals, account):\n        res = self.get_multitoken_balance(token_symbol, token_address, token_decimals, [account])\n        return res.get(account, 0)\n\n    def get_block_by_number(self, num):\n        if not self.connected:\n            return None\n\n        return self.web3.eth.getBlock(num)\n", "path": "rotkehlchen/ethchain.py"}], "after_files": [{"content": "import os\nfrom web3 import Web3, HTTPProvider\nfrom requests import ConnectionError\n\nfrom rotkehlchen.utils import from_wei, rlk_jsonloads, request_get\nfrom rotkehlchen.fval import FVal\n\nimport logging\nlogger = logging.getLogger(__name__)\n\n\nclass Ethchain(object):\n    def __init__(self, ethrpc_port, attempt_connect=True):\n        self.web3 = None\n        self.rpc_port = ethrpc_port\n        self.connected = False\n        if attempt_connect:\n            self.attempt_connect(ethrpc_port)\n\n    def attempt_connect(self, ethrpc_port, mainnet_check=True):\n        if self.rpc_port == ethrpc_port and self.connected:\n            # We are already connected\n            return True, 'Already connected to an ethereum node'\n\n        if self.web3:\n            del self.web3\n\n        try:\n            self.web3 = Web3(HTTPProvider('http://localhost:{}'.format(ethrpc_port)))\n        except ConnectionError:\n            logger.warn('Could not connect to a local ethereum node. Will use etherscan only')\n            self.connected = False\n            return False, 'Failed to connect to ethereum node at port {}'.format(ethrpc_port)\n\n        if self.web3.isConnected():\n            dir_path = os.path.dirname(os.path.realpath(__file__))\n            with open(os.path.join(dir_path, 'data', 'token_abi.json'), 'r') as f:\n                self.token_abi = rlk_jsonloads(f.read())\n\n            # Also make sure we are actually connected to the Ethereum mainnet\n            if mainnet_check:\n                genesis_hash = self.web3.eth.getBlock(0)['hash'].hex()\n                target = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3'\n                if genesis_hash != target:\n                    logger.warn(\n                        'Connected to a local ethereum node but it is not on the ethereum mainnet'\n                    )\n                    self.connected = False\n                    message = (\n                        'Connected to ethereum node at port {} but it is not on '\n                        'the ethereum mainnet'.format(ethrpc_port)\n                    )\n                    return False, message\n\n            self.connected = True\n            return True, ''\n        else:\n            logger.warn('Could not connect to a local ethereum node. Will use etherscan only')\n            self.connected = False\n            message = 'Failed to connect to ethereum node at port {}'.format(ethrpc_port)\n\n        # If we get here we did not connnect\n        return False, message\n\n    def set_rpc_port(self, port):\n        \"\"\" Attempts to set the RPC port for the ethereum client.\n\n        Returns a tuple (result, message)\n            - result: Boolean for success or failure of changing the rpc port\n            - message: A message containing information on what happened. Can\n                       be populated both in case of success or failure\"\"\"\n        result, message = self.attempt_connect(port)\n        if result:\n            self.ethrpc_port = port\n        return result, message\n\n    def get_eth_balance(self, account):\n        if not self.connected:\n            eth_resp = request_get(\n                'https://api.etherscan.io/api?module=account&action=balance&address=%s'\n                % account\n            )\n            if eth_resp['status'] != 1:\n                raise ValueError('Failed to query etherscan for accounts balance')\n            amount = FVal(eth_resp['result'])\n            return from_wei(amount)\n        else:\n            return from_wei(self.web3.eth.getBalance(account))\n\n    def get_multieth_balance(self, accounts):\n        \"\"\"Returns a dict with keys being accounts and balances in ETH\"\"\"\n        balances = {}\n\n        if not self.connected:\n            if len(accounts) > 20:\n                new_accounts = [accounts[x:x+2] for x in range(0, len(accounts), 2)]\n            else:\n                new_accounts = [accounts]\n\n            for account_slice in new_accounts:\n                eth_resp = request_get(\n                    'https://api.etherscan.io/api?module=account&action=balancemulti&address=%s' %\n                    ','.join(account_slice)\n                )\n                if eth_resp['status'] != 1:\n                    raise ValueError('Failed to query etherscan for accounts balance')\n                eth_accounts = eth_resp['result']\n\n                for account_entry in eth_accounts:\n                    amount = FVal(account_entry['balance'])\n                    balances[account_entry['account']] = from_wei(amount)\n\n        else:\n            for account in accounts:\n                amount = FVal(self.web3.eth.getBalance(account))\n                balances[account] = from_wei(amount)\n\n        return balances\n\n    def get_multitoken_balance(self, token_symbol, token_address, token_decimals, accounts):\n        \"\"\"Return a dictionary with keys being accounts and value balances of token\n        Balance value is normalized through the token decimals.\n        \"\"\"\n        balances = {}\n        if self.connected:\n            token_contract = self.web3.eth.contract(\n                address=token_address,\n                abi=self.token_abi\n            )\n            for account in accounts:\n                token_amount = FVal(token_contract.functions.balanceOf(account).call())\n                if token_amount != 0:\n                    balances[account] = token_amount / (FVal(10) ** FVal(token_decimals))\n        else:\n            for account in accounts:\n                print('Checking token {} for account {}'.format(token_symbol, account))\n                resp = request_get(\n                    'https://api.etherscan.io/api?module=account&action='\n                    'tokenbalance&contractaddress={}&address={}'.format(\n                        token_address,\n                        account,\n                    ))\n                if resp['status'] != 1:\n                    raise ValueError(\n                        'Failed to query etherscan for {} token balance of {}'.format(\n                            token_symbol,\n                            account,\n                        ))\n                token_amount = FVal(resp['result'])\n                if token_amount != 0:\n                    balances[account] = token_amount / (FVal(10) ** FVal(token_decimals))\n\n        return balances\n\n    def get_token_balance(self, token_symbol, token_address, token_decimals, account):\n        res = self.get_multitoken_balance(token_symbol, token_address, token_decimals, [account])\n        return res.get(account, 0)\n\n    def get_block_by_number(self, num):\n        if not self.connected:\n            return None\n\n        return self.web3.eth.getBlock(num)\n", "path": "rotkehlchen/ethchain.py"}]}