From 31196a52ca80950c8cb09eb6399b26ea24410e29 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 13 Jul 2018 20:34:35 +0100 Subject: [PATCH] Merge #12944: [wallet] ScanforWalletTransactions should mark input txns as dirty 3c292cc19 ScanforWalletTransactions should mark input txns as dirty (Gregory Sanders) Pull request description: I'm hitting a corner case in my mainnet wallet where I load a restore a wallet, call `rescanblockchain` from RPC, and it's "double counting" an output I've sent to myself since currently it never marks input transactions as dirty. This is fixed by a restart of the wallet. Note that this only happens with keys with birthdate *after* the blocks containing the spent funds which gets scanned on startup, so it's hard to test without a set seed function. Tree-SHA512: ee1fa152bb054b57ab4c734e355df10d241181e0372c81d583be61678fffbabe5ae60b09b05dc1bbbcfb4838df9d8538791d4c1d80a09b84d78ad2f50dcb0a61 --- src/wallet/wallet.cpp | 6 +++--- src/wallet/wallet.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4580a0aecd35f0..a6064d99eb25d3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1430,10 +1430,10 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) fAnonymizableTallyCachedNonDenom = false; } -void CWallet::SyncTransaction(const CTransactionRef& ptx, const CBlockIndex *pindex, int posInBlock) { +void CWallet::SyncTransaction(const CTransactionRef& ptx, const CBlockIndex *pindex, int posInBlock, bool update_tx) { const CTransaction& tx = *ptx; - if (!AddToWalletIfInvolvingMe(ptx, pindex, posInBlock, true)) + if (!AddToWalletIfInvolvingMe(ptx, pindex, posInBlock, update_tx)) return; // Not one of ours // If a transaction changes 'conflicted' state, that changes the balance @@ -2231,7 +2231,7 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, CBlock break; } for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) { - AddToWalletIfInvolvingMe(block.vtx[posInBlock], pindex, posInBlock, fUpdate); + SyncTransaction(block.vtx[posInBlock], pindex, posInBlock, fUpdate); } } else { ret = pindex; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index ac428a5c38a01e..52efc2b3bbe53c 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -740,9 +740,9 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface void SyncMetaData(std::pair); - /* Used by TransactionAddedToMemorypool/BlockConnected/Disconnected. + /* Used by TransactionAddedToMemorypool/BlockConnected/Disconnected/ScanForWalletTransactions. * Should be called with pindexBlock and posInBlock if this is for a transaction that is included in a block. */ - void SyncTransaction(const CTransactionRef& tx, const CBlockIndex *pindex = nullptr, int posInBlock = 0) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + void SyncTransaction(const CTransactionRef& tx, const CBlockIndex *pindex = nullptr, int posInBlock = 0, bool update_tx = true) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); /* HD derive new child key (on internal or external chain) */ void DeriveNewChildKey(WalletBatch &batch, const CKeyMetadata& metadata, CKey& secretRet, uint32_t nAccountIndex, bool fInternal /*= false*/) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);