jgarzik / python-bitcoinrpc

Python interface to bitcoin's JSON-RPC API
GNU Lesser General Public License v2.1
644 stars 304 forks source link

Convert Decimal to float, then round to prevent InvalidOperation err #109

Open rrybarczyk opened 2 years ago

rrybarczyk commented 2 years ago

Bug found when calling <rpc_conn>.getmininginfo().

Error:

project/rpc.py:171: in get_mining_info
    return self.conn.getmininginfo()
python3.9/site-packages/bitcoinrpc/authproxy.py:140: in __call__
    response = self._get_response()
python3.9/site-packages/bitcoinrpc/authproxy.py:193: in _get_response
    log.debug("<-%s- %s"%(response["id"], json.dumps(response["result"], default=EncodeDecimal)))
/usr/lib/python3.9/json/__init__.py:234: in dumps
    return cls(
/usr/lib/python3.9/json/encoder.py:199: in encode
    chunks = self.iterencode(o, _one_shot=True)
/usr/lib/python3.9/json/encoder.py:257: in iterencode
    return _iterencode(o, 0)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

o = Decimal('1.995597991444473E+20')

    def EncodeDecimal(o):
        if isinstance(o, decimal.Decimal):
            #  return round(float(o), 8)
>           return float(round(o, 8))
E           decimal.InvalidOperation: [<class 'decimal.InvalidOperation'>]

python3.9/site-packages/bitcoinrpc/authproxy.py:78: InvalidOperation

Fix:

Switch order of float cast and round operations from:

def EncodeDecimal(o):
    if isinstance(o, decimal.Decimal):
        return float(round(o, 8))
    raise TypeError(repr(o) + " is not JSON serializable")

To:

def EncodeDecimal(o):
    if isinstance(o, decimal.Decimal):
        return round(float(o), 8)
    raise TypeError(repr(o) + " is not JSON serializable")