# Buggy code
def query_balances(self, requested_save_data=False):
    balances = {}
    problem_free = True
    for exchange in self.connected_exchanges:
        exchange_balances, msg = getattr(self, exchange).query_balances()
        # If we got an error, disregard that exchange but make sure we don't save data
        if not exchange_balances:
            problem_free = False
        else:
            balances[exchange] = exchange_balances

    result = self.blockchain.query_balances()["totals"]
    if result != {}:
        balances["blockchain"] = result

    result = self.query_fiat_balances()
    if result != {}:
        balances["banks"] = result

    combined = combine_stat_dicts([v for k, v in balances.items()])
    total_usd_per_location = [
        (k, dict_get_sumof(v, "usd_value")) for k, v in balances.items()
    ]

    # calculate net usd value
    net_usd = FVal(0)
    for k, v in combined.items():
        net_usd += FVal(v["usd_value"])

    stats = {"location": {}, "net_usd": net_usd}
    for entry in total_usd_per_location:
        name = entry[0]
        total = entry[1]
        stats["location"][name] = {
            "usd_value": total,
            "percentage_of_net_value": (total / net_usd).to_percentage(),
        }

    for k, v in combined.items():
        combined[k]["percentage_of_net_value"] = (
            v["usd_value"] / net_usd
        ).to_percentage()

    result_dict = merge_dicts(combined, stats)

    allowed_to_save = requested_save_data or self.data.should_save_balances()
    if problem_free and allowed_to_save:
        self.data.save_balances_data(result_dict)

    # After adding it to the saved file we can overlay additional data that
    # is not required to be saved in the history file
    try:
        details = self.data.accountant.details
        for asset, (tax_free_amount, average_buy_value) in details.items():
            if asset not in result_dict:
                continue

            result_dict[asset]["tax_free_amount"] = tax_free_amount
            result_dict[asset]["average_buy_value"] = average_buy_value

            current_price = (
                result_dict[asset]["usd_value"] / result_dict[asset]["amount"]
            )
            if average_buy_value != FVal(0):
                result_dict[asset]["percent_change"] = (
                    (current_price - average_buy_value) / average_buy_value
                ) * 100
            else:
                result_dict[asset]["percent_change"] = "INF"

    except AttributeError:
        pass

    return result_dict


# Traceback (zerorpc.exceptions.RemoteError)
Traceback (most recent call last):
File "/home/lefteris/.virtualenvs/rotkehlchen/bin/zerorpc", line 11, in <module>
load_entry_point('zerorpc==0.6.1', 'console_scripts', 'zerorpc')()
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/zerorpc/cli.py", line 310, in main
return run_client(args)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/zerorpc/cli.py", line 269, in run_client
results = client(args.command, *call_args)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/zerorpc/core.py", line 270, in __call__
return self._process_response(request_event, bufchan, timeout)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/zerorpc/core.py", line 238, in _process_response
reply_event, self._handle_remote_error)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/zerorpc/patterns.py", line 45, in process_answer
raise exception
zerorpc.exceptions.RemoteError: Traceback (most recent call last):
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/web3/contract.py", line 1214, in call_contract_function
output_data = decode_abi(output_types, return_data)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/eth_abi/abi.py", line 96, in decode_abi
return decoder(stream)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/eth_abi/decoding.py", line 118, in __call__
return self.decode(stream)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/eth_utils/functional.py", line 22, in inner
return callback(fn(*args, **kwargs))
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/eth_abi/decoding.py", line 164, in decode
yield decoder(stream)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/eth_abi/decoding.py", line 118, in __call__
return self.decode(stream)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/eth_abi/decoding.py", line 186, in decode
raw_data = self.read_data_from_stream(stream)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/eth_abi/decoding.py", line 279, in read_data_from_stream
len(data),
eth_abi.exceptions.InsufficientDataBytes: Tried to read 32 bytes.  Only got 0 bytes

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/zerorpc/core.py", line 153, in _async_task
functor.pattern.process_call(self._context, bufchan, event, functor)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/zerorpc/patterns.py", line 30, in process_call
result = functor(*req_event.args)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/zerorpc/decorators.py", line 44, in __call__
return self._functor(*args, **kargs)
File "/home/lefteris/w/rotkehlchen/rotkehlchen/server.py", line 229, in query_balances
result = self.rotkehlchen.query_balances(save_data)
File "/home/lefteris/w/rotkehlchen/rotkehlchen/rotkehlchen.py", line 417, in query_balances
result = self.blockchain.query_balances()['totals']
File "/home/lefteris/w/rotkehlchen/rotkehlchen/utils.py", line 83, in wrapper
result = f(wrappingobj, *args)
File "/home/lefteris/w/rotkehlchen/rotkehlchen/blockchain.py", line 79, in query_balances
self.query_ethereum_balances()
File "/home/lefteris/w/rotkehlchen/rotkehlchen/blockchain.py", line 321, in query_ethereum_balances
self.query_ethereum_tokens(self.owned_eth_tokens, eth_balances)
File "/home/lefteris/w/rotkehlchen/rotkehlchen/blockchain.py", line 286, in query_ethereum_tokens
self.accounts[S_ETH],
File "/home/lefteris/w/rotkehlchen/rotkehlchen/ethchain.py", line 142, in get_multitoken_balance
token_amount = FVal(token_contract.functions.balanceOf(account).call())
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/web3/contract.py", line 979, in call
**self.kwargs)
File "/home/lefteris/.virtualenvs/rotkehlchen/lib/python3.6/site-packages/web3/contract.py", line 1236, in call_contract_function
raise BadFunctionCallOutput(msg) from e
web3.exceptions.BadFunctionCallOutput: Could not transact with/call contract function, is contract deployed correctly and chain synced?

# Fixed code
def query_balances(self, requested_save_data=False):
    balances = {}
    problem_free = True
    for exchange in self.connected_exchanges:
        exchange_balances, msg = getattr(self, exchange).query_balances()
        # If we got an error, disregard that exchange but make sure we don't save data
        if not exchange_balances:
            problem_free = False
        else:
            balances[exchange] = exchange_balances

    result, error_or_empty = self.blockchain.query_balances()
    if error_or_empty == "":
        balances["blockchain"] = result["totals"]
    else:
        problem_free = False

    result = self.query_fiat_balances()
    if result != {}:
        balances["banks"] = result

    combined = combine_stat_dicts([v for k, v in balances.items()])
    total_usd_per_location = [
        (k, dict_get_sumof(v, "usd_value")) for k, v in balances.items()
    ]

    # calculate net usd value
    net_usd = FVal(0)
    for k, v in combined.items():
        net_usd += FVal(v["usd_value"])

    stats = {"location": {}, "net_usd": net_usd}
    for entry in total_usd_per_location:
        name = entry[0]
        total = entry[1]
        stats["location"][name] = {
            "usd_value": total,
            "percentage_of_net_value": (total / net_usd).to_percentage(),
        }

    for k, v in combined.items():
        combined[k]["percentage_of_net_value"] = (
            v["usd_value"] / net_usd
        ).to_percentage()

    result_dict = merge_dicts(combined, stats)

    allowed_to_save = requested_save_data or self.data.should_save_balances()
    if problem_free and allowed_to_save:
        self.data.save_balances_data(result_dict)

    # After adding it to the saved file we can overlay additional data that
    # is not required to be saved in the history file
    try:
        details = self.data.accountant.details
        for asset, (tax_free_amount, average_buy_value) in details.items():
            if asset not in result_dict:
                continue

            result_dict[asset]["tax_free_amount"] = tax_free_amount
            result_dict[asset]["average_buy_value"] = average_buy_value

            current_price = (
                result_dict[asset]["usd_value"] / result_dict[asset]["amount"]
            )
            if average_buy_value != FVal(0):
                result_dict[asset]["percent_change"] = (
                    (current_price - average_buy_value) / average_buy_value
                ) * 100
            else:
                result_dict[asset]["percent_change"] = "INF"

    except AttributeError:
        pass

    return result_dict