From d74d4abefc72aeb66f3063a074889100e7cfa155 Mon Sep 17 00:00:00 2001 From: Leon Costa Date: Thu, 4 Jul 2024 18:50:17 +0200 Subject: [PATCH] Fix wallet load error on incomplete gettransaction The error happens when the wallet has some locked outputs in `listlockunspent` and the corresponding `gettransaction` doesn't contain the details of this particular output. It may be related to https://github.com/bitcoin/bitcoin/issues/28555. It is at least the same symptom. The locked outputs were locked by creating a transaction in Specter. This has happened to me multiple times. The UI says it failed to load the wallet with the following error: Failed to load utxos, IndexError: list index out of range The raw transaction does contain the missing output so we use that instead. Here's an example that generates the error: listlockunspent: [ { "txid": "", "vout": 0 } ] gettransaction : { "amount": , "fee": , "confirmations": , "blockhash": "", "blockheight": , "blockindex": , "blocktime": , "txid": "", "wtxid": "", "walletconflicts": [ ], "time": , "timereceived": , "bip125-replaceable": "no", "details": [ { "address": "", "category": "send", "amount": , "label": "", "vout": 1, "fee": , "abandoned": false } ], "hex": "", "lastprocessedblock": { "hash": "", "height": } } decoderawtransaction : { "txid": "", "hash": "", "version": 2, "size": , "vsize": , "weight": , "locktime": , "vin": [ { "txid": "", "vout": 0, "scriptSig": { "asm": "", "hex": "" }, "txinwitness": [ "", "" ], "sequence": } ], "vout": [ { "value": , "n": 0, "scriptPubKey": { "asm": "", "desc": "", "hex": "", "address": "", "type": "" } }, { "value": , "n": 1, "scriptPubKey": { "asm": "", "desc": "", "hex": "", "address": "", "type": "" } } ] } --- src/cryptoadvance/specter/wallet/wallet.py | 23 ++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/cryptoadvance/specter/wallet/wallet.py b/src/cryptoadvance/specter/wallet/wallet.py index 4340b3d8f..6b6d1ca94 100644 --- a/src/cryptoadvance/specter/wallet/wallet.py +++ b/src/cryptoadvance/specter/wallet/wallet.py @@ -718,13 +718,28 @@ def check_utxo(self): else: tx_from_core = self.rpc.gettransaction(tx_copy["txid"]) # in the case of locked amounts, the stupid listlockunspent call does not contain reasonable utxo-data - searched_vout = [ + searched_vouts = [ _tx for _tx in tx_from_core["details"] if _tx["vout"] == utxo_vout - ][0] - tx_copy["amount"] = searched_vout["amount"] - tx_copy["address"] = searched_vout["address"] + ] + if len(searched_vouts) > 0: + searched_vout = searched_vouts[0] + tx_copy["amount"] = searched_vout["amount"] + tx_copy["address"] = searched_vout["address"] + else: + # Sometimes gettransaction doesn't return the complete list of outputs. + # It may be related to https://github.com/bitcoin/bitcoin/issues/28555 + # In this case we decode the raw transaction to get the data we want. + raw_transaction_hex = tx_from_core["hex"] + raw_transaction = self.rpc.decoderawtransaction(raw_transaction_hex) + searched_raw_vout = [ + _output + for _output in raw_transaction["vout"] + if _output["n"] == utxo_vout + ][0] + tx_copy["amount"] = searched_raw_vout["value"] + tx_copy["address"] = searched_raw_vout["scriptPubKey"]["address"] # Append the copy to the _full_utxo list _full_utxo.append(tx_copy)