diff --git a/plugins/currency/bitcoin/bitcoind_ b/plugins/currency/bitcoin/bitcoind_ index 12fe03bd..4bdf75e0 100755 --- a/plugins/currency/bitcoin/bitcoind_ +++ b/plugins/currency/bitcoin/bitcoind_ @@ -63,6 +63,45 @@ import urllib.request DEBUG = os.getenv('MUNIN_DEBUG') == '1' +def _get_version(info): + # v0.15.2 version is represented as 150200 + return info['version'] // 10000 + + +def _rpc_get_initial_info(connection): + (info, connect_error) = connection.getnetworkinfo() + if connect_error: + if isinstance(connect_error, urllib.error.HTTPError) and connect_error.code == 404: + # getinfo RPC exists in version <= 0.15 + (info, connect_error) = connection.getinfo() + if connect_error: + return (None, None, connect_error) + else: + return (None, None, connect_error) # pass all other not-404 errors + + return (info, _get_version(info), None) + + +def _rpc_get_balance(info, minor_version, connection): + # see https://github.com/bitcoin/bitcoin/blob/239d199667888e5d60309f15a38eed4d3afe56c4/ + # doc/release-notes/release-notes-0.19.0.1.md#new-rpcs + if minor_version >= 19: + # we use getbalance*s* (plural) as old getbalance is being deprecated, + # and we have to calculate total balance (owned and watch-only) manually now. + (result, error) = connection.getbalances() + + total = sum(result[wallet_mode]['trusted'] + for wallet_mode in ('mine', 'watchonly') + if wallet_mode in result) + + info['balance'] = total + return info + else: + (result, error) = connection.getbalance() + info['balance'] = result + return info + + def main(): # getinfo variable is read from command name - probably the sym-link name. request_var = sys.argv[0].split('_', 1)[1] or 'balance' @@ -119,7 +158,7 @@ def main(): bitcoin_options.rpcport), username=bitcoin_options.rpcuser, password=bitcoin_options.rpcpassword) - (info, connect_error) = bitcoin.getnetworkinfo() + (info, minor_version, connect_error) = _rpc_get_initial_info(bitcoin) if connect_error: error = "Could not connect to Bitcoin server: {}".format(connect_error) @@ -135,15 +174,7 @@ def main(): return False if request_var == 'balance': - # we use getbalance*s* (plural) as old getbalance is being deprecated, - # and we have to calculate total balance (owned and watch-only) manually now. - (info, error) = bitcoin.getbalances() - - total = sum(info[wallet_mode]['trusted'] - for wallet_mode in ('mine', 'watchonly') - if wallet_mode in info) - - info['balance'] = total + info = _rpc_get_balance(info, minor_version, bitcoin) if request_var in ('transactions', 'block_age'): (info, error) = bitcoin.getblockchaininfo()