aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGregory Sanders <gsanders87@gmail.com>2019-11-27 10:56:04 -0500
committerGregory Sanders <gsanders87@gmail.com>2020-01-03 17:20:46 -0500
commit09502452bbbe21bb974f1de8cf53196373921ab9 (patch)
tree04158fc82f0681682f28feded28957fd9f7f8994 /src
parentd8a66626d63135fd245d5afc524b88b9a94d208b (diff)
downloadbitcoin-09502452bbbe21bb974f1de8cf53196373921ab9.tar.xz
IsUsedDestination should count any known single-key address
Diffstat (limited to 'src')
-rw-r--r--src/wallet/rpcwallet.cpp2
-rw-r--r--src/wallet/wallet.cpp30
-rw-r--r--src/wallet/wallet.h5
3 files changed, 26 insertions, 11 deletions
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index d906f6ddf0..a1d4603174 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -2927,7 +2927,7 @@ static UniValue listunspent(const JSONRPCRequest& request)
CTxDestination address;
const CScript& scriptPubKey = out.tx->tx->vout[out.i].scriptPubKey;
bool fValidAddress = ExtractDestination(scriptPubKey, address);
- bool reused = avoid_reuse && pwallet->IsUsedDestination(address);
+ bool reused = avoid_reuse && pwallet->IsUsedDestination(out.tx->GetHash(), out.i);
if (destinations.size() && (!fValidAddress || !destinations.count(address)))
continue;
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index b1e1385ca3..ac167d108a 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -719,17 +719,33 @@ void CWallet::SetUsedDestinationState(WalletBatch& batch, const uint256& hash, u
}
}
-bool CWallet::IsUsedDestination(const CTxDestination& dst) const
-{
- LOCK(cs_wallet);
- return IsMine(dst) && GetDestData(dst, "used", nullptr);
-}
-
bool CWallet::IsUsedDestination(const uint256& hash, unsigned int n) const
{
+ AssertLockHeld(cs_wallet);
CTxDestination dst;
const CWalletTx* srctx = GetWalletTx(hash);
- return srctx && ExtractDestination(srctx->tx->vout[n].scriptPubKey, dst) && IsUsedDestination(dst);
+ if (srctx) {
+ assert(srctx->tx->vout.size() > n);
+ LegacyScriptPubKeyMan* spk_man = GetLegacyScriptPubKeyMan();
+ // When descriptor wallets arrive, these additional checks are
+ // likely superfluous and can be optimized out
+ assert(spk_man != nullptr);
+ for (const auto& keyid : GetAffectedKeys(srctx->tx->vout[n].scriptPubKey, *spk_man)) {
+ WitnessV0KeyHash wpkh_dest(keyid);
+ if (GetDestData(wpkh_dest, "used", nullptr)) {
+ return true;
+ }
+ ScriptHash sh_wpkh_dest(wpkh_dest);
+ if (GetDestData(sh_wpkh_dest, "used", nullptr)) {
+ return true;
+ }
+ PKHash pkh_dest(keyid);
+ if (GetDestData(pkh_dest, "used", nullptr)) {
+ return true;
+ }
+ }
+ }
+ return false;
}
bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 51df4a9a8b..4a4b28e699 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -810,9 +810,8 @@ public:
bool IsSpent(const uint256& hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
- // Whether this or any UTXO with the same CTxDestination has been spent.
- bool IsUsedDestination(const CTxDestination& dst) const;
- bool IsUsedDestination(const uint256& hash, unsigned int n) const;
+ // Whether this or any known UTXO with the same single key has been spent.
+ bool IsUsedDestination(const uint256& hash, unsigned int n) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void SetUsedDestinationState(WalletBatch& batch, const uint256& hash, unsigned int n, bool used) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
std::vector<OutputGroup> GroupOutputs(const std::vector<COutput>& outputs, bool single_coin) const;