From a537d7aaa069bc216aeab381bbc4d312b5ffedf1 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Fri, 22 Jul 2022 15:30:10 -0400 Subject: [PATCH] wallet: SelectExternal actually external inputs If an external input's utxo was created by a transaction that the wallet knows about, then it would not be selected using SelectExternal. This results in either funding failure or incorrect weight calculation. --- src/wallet/spend.cpp | 12 ++++++++---- test/functional/rpc_fundrawtransaction.py | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index d6362c1f143..bffb665fa85 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -1127,12 +1127,16 @@ bool FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& nFeeRet, wallet.chain().findCoins(coins); for (const CTxIn& txin : tx.vin) { - // if it's not in the wallet and corresponding UTXO is found than select as external output const auto& outPoint = txin.prevout; - if (wallet.mapWallet.find(outPoint.hash) == wallet.mapWallet.end() && !coins[outPoint].out.IsNull()) { - coinControl.SelectExternal(outPoint, coins[outPoint].out); - } else { + if (wallet.IsMine(outPoint)) { + // The input was found in the wallet, so select as internal coinControl.Select(outPoint); + } else if (coins[outPoint].out.IsNull()) { + error = _("Unable to find UTXO for external input"); + return false; + } else { + // The input was not in the wallet, but is in the UTXO set, so select as external + coinControl.SelectExternal(outPoint, coins[outPoint].out); } } diff --git a/test/functional/rpc_fundrawtransaction.py b/test/functional/rpc_fundrawtransaction.py index cf9ad3f458d..d07c31a532c 100755 --- a/test/functional/rpc_fundrawtransaction.py +++ b/test/functional/rpc_fundrawtransaction.py @@ -408,7 +408,7 @@ class RawTransactionsTest(BitcoinTestFramework): inputs = [ {'txid' : "1c7f966dab21119bac53213a2bc7532bff1fa844c124fd750a7d0b1332440bd1", 'vout' : 0} ] #invalid vin! outputs = { self.nodes[0].getnewaddress() : 1.0} rawtx = self.nodes[2].createrawtransaction(inputs, outputs) - assert_raises_rpc_error(-4, "Insufficient funds", self.nodes[2].fundrawtransaction, rawtx) + assert_raises_rpc_error(-4, "Unable to find UTXO for external input", self.nodes[2].fundrawtransaction, rawtx) def test_fee_p2pkh(self): """Compare fee of a standard pubkeyhash transaction."""