From f2d00bfe1a32a11c0d88e8c1d3bae6a6b01db15e Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Fri, 22 Jul 2022 14:49:10 -0400 Subject: wallet: Add CWallet::IsMine(COutPoint) It is useful to have an IsMine function that can take an outpoint. --- src/wallet/wallet.cpp | 13 +++++++++++++ src/wallet/wallet.h | 1 + 2 files changed, 14 insertions(+) (limited to 'src/wallet') diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 45f49954a3..02fe6fba5b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1421,6 +1421,19 @@ bool CWallet::IsMine(const CTransaction& tx) const return false; } +isminetype CWallet::IsMine(const COutPoint& outpoint) const +{ + AssertLockHeld(cs_wallet); + auto wtx = GetWalletTx(outpoint.hash); + if (!wtx) { + return ISMINE_NO; + } + if (outpoint.n >= wtx->tx->vout.size()) { + return ISMINE_NO; + } + return IsMine(wtx->tx->vout[outpoint.n]); +} + bool CWallet::IsFromMe(const CTransaction& tx) const { return (GetDebit(tx, ISMINE_ALL) > 0); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 247c172da3..d8c54bdb01 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -684,6 +684,7 @@ public: CAmount GetDebit(const CTxIn& txin, const isminefilter& filter) const; isminetype IsMine(const CTxOut& txout) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); bool IsMine(const CTransaction& tx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + isminetype IsMine(const COutPoint& outpoint) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); /** should probably be renamed to IsRelevantToMe */ bool IsFromMe(const CTransaction& tx) const; CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const; -- cgit v1.2.3 From a537d7aaa069bc216aeab381bbc4d312b5ffedf1 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Fri, 22 Jul 2022 15:30:10 -0400 Subject: 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 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/wallet') diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index d6362c1f14..bffb665fa8 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); } } -- cgit v1.2.3 From eb879634db2116b23e884dab21318743f974f1f3 Mon Sep 17 00:00:00 2001 From: Andrew Chow Date: Fri, 22 Jul 2022 15:47:06 -0400 Subject: wallet: Try estimating input size with external data if wallet fails Instead of choosing whether to use the wallet or external data when estimating the size of an input, first use the wallet, then try external data if that failed. --- src/wallet/spend.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/wallet') diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index bffb665fa8..001acd04e2 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -569,8 +569,12 @@ std::optional SelectCoins(const CWallet& wallet, CoinsResult& a if (!coin_control.GetExternalOutput(outpoint, txout)) { return std::nullopt; } + } + + if (input_bytes == -1) { input_bytes = CalculateMaximumSignedInputSize(txout, outpoint, &coin_control.m_external_provider, &coin_control); } + // If available, override calculated size with coin control specified size if (coin_control.HasInputWeight(outpoint)) { input_bytes = GetVirtualTransactionSize(coin_control.GetInputWeight(outpoint), 0, 0); -- cgit v1.2.3