From be6735dca61aedb4076e4fe61c25ef99a655e90c Mon Sep 17 00:00:00 2001 From: AdamISZ Date: Tue, 27 Nov 2018 21:26:30 +0100 Subject: [PATCH] Handle invalid utxos in query_utxo_set Previous to this commit, if a utxo string did not conform to the standard txid:n in hex format, of the correct length, an exception would be thrown (specifically for invalid values of the output index, which must be parseable as an integer). This could allow a taker to crash a maker by sending an invalid commitment string. After this commit this invalid utxo is correctly ignored (and the commitment of course is invalid). --- jmclient/jmclient/blockchaininterface.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/jmclient/jmclient/blockchaininterface.py b/jmclient/jmclient/blockchaininterface.py index 23b52f1..aabff0b 100644 --- a/jmclient/jmclient/blockchaininterface.py +++ b/jmclient/jmclient/blockchaininterface.py @@ -829,11 +829,31 @@ class BitcoinCoreInterface(BlockchainInterface): return True def query_utxo_set(self, txout, includeconf=False, includeunconf=False): + """If txout is either (a) a single string in hex encoded txid:n form, + or a list of the same, returns, as a list for each txout item, + the result of gettxout from the bitcoind rpc for those utxs; + if any utxo is invalid, None is returned. + includeconf: if this is True, the current number of confirmations + of the prescribed utxo is included in the returned result dict. + includeunconf: if True, utxos which currently have zero confirmations + are included in the result set. + If the utxo is of a non-standard type such that there is no address, + the address field in the dict is None. + """ if not isinstance(txout, list): txout = [txout] result = [] for txo in txout: - ret = self.rpc('gettxout', [txo[:64], int(txo[65:]), includeunconf]) + if len(txo) < 66: + result.append(None) + continue + try: + txo_idx = int(txo[65:]) + except ValueError: + log.warn("Invalid utxo format, ignoring: {}".format(txo)) + result.append(None) + continue + ret = self.rpc('gettxout', [txo[:64], txo_idx, includeunconf]) if ret is None: result.append(None) else: