diff options
author | Tom Harding <tomh@thinlink.com> | 2014-06-26 18:31:05 -0700 |
---|---|---|
committer | Tom Harding <tomh@thinlink.com> | 2014-06-27 07:54:21 -0700 |
commit | ada5a067c75f19a724cc054286ecf2254e5dbe8f (patch) | |
tree | dcbb99b8eb6dcce4c9ab8eae70f9a4923ca5f664 /src/wallet.cpp | |
parent | d640a3ceab4f4372c2a0f738c1286cfde4b41b50 (diff) |
UI to alert of respend attempt affecting wallet.
Respend transactions that conflict with transactions already in the
wallet are added to it. They are not displayed unless they also involve
the wallet, or get into a block. If they do not involve the wallet,
they continue not to affect balance.
Transactions that involve the wallet, and have conflicting non-equivalent
transactions, are highlighted in red. When the conflict first occurs, a
modal dialog is thrown.
CWallet::SyncMetaData is changed to sync only to equivalent transactions.
When a conflict is added to the wallet, counter nConflictsReceived is
incremented. This acts like a change in active block height for the
purpose of triggering UI updates.
Diffstat (limited to 'src/wallet.cpp')
-rw-r--r-- | src/wallet.cpp | 33 |
1 files changed, 27 insertions, 6 deletions
diff --git a/src/wallet.cpp b/src/wallet.cpp index f6fd6e958d..79cc5ba3c9 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -256,7 +256,7 @@ bool CWallet::SetMaxVersion(int nVersion) return true; } -set<uint256> CWallet::GetConflicts(const uint256& txid) const +set<uint256> CWallet::GetConflicts(const uint256& txid, bool includeEquivalent) const { set<uint256> result; AssertLockHeld(cs_wallet); @@ -274,7 +274,8 @@ set<uint256> CWallet::GetConflicts(const uint256& txid) const continue; // No conflict if zero or one spends range = mapTxSpends.equal_range(txin.prevout); for (TxSpends::const_iterator it = range.first; it != range.second; ++it) - result.insert(it->second); + if (includeEquivalent || !wtx.IsEquivalentTo(mapWallet.at(it->second))) + result.insert(it->second); } return result; } @@ -303,6 +304,7 @@ void CWallet::SyncMetaData(pair<TxSpends::iterator, TxSpends::iterator> range) const uint256& hash = it->second; CWalletTx* copyTo = &mapWallet[hash]; if (copyFrom == copyTo) continue; + if (!copyFrom->IsEquivalentTo(*copyTo)) continue; copyTo->mapValue = copyFrom->mapValue; copyTo->vOrderForm = copyFrom->vOrderForm; // fTimeReceivedIsTxTime not copied on purpose @@ -588,6 +590,20 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) // Notify UI of new or updated transaction NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED); + // Notifications for existing transactions that now have conflicts with this one + if (fInsertedNew) + { + BOOST_FOREACH(const uint256& conflictHash, wtxIn.GetConflicts(false)) + { + CWalletTx& txConflict = mapWallet[conflictHash]; + NotifyTransactionChanged(this, conflictHash, CT_UPDATED); //Updates UI table + if (IsFromMe(txConflict) || IsMine(txConflict)) + { + NotifyTransactionChanged(this, conflictHash, CT_GOT_CONFLICT); //Throws dialog + } + } + } + // notify an external script when a wallet transaction comes in or is updated std::string strCmd = GetArg("-walletnotify", ""); @@ -610,7 +626,12 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pbl AssertLockHeld(cs_wallet); bool fExisted = mapWallet.count(tx.GetHash()); if (fExisted && !fUpdate) return false; - if (fExisted || IsMine(tx) || IsFromMe(tx)) + + bool fIsConflicting = IsConflicting(tx); + if (fIsConflicting) + nConflictsReceived++; + + if (fExisted || IsMine(tx) || IsFromMe(tx) || fIsConflicting) { CWalletTx wtx(this,tx); // Get merkle branch if transaction was found in a block @@ -896,7 +917,7 @@ void CWallet::ReacceptWalletTransactions() int nDepth = wtx.GetDepthInMainChain(); - if (!wtx.IsCoinBase() && nDepth < 0) + if (!wtx.IsCoinBase() && nDepth < 0 && (IsMine(wtx) || IsFromMe(wtx))) { // Try to add to memory pool LOCK(mempool.cs); @@ -916,13 +937,13 @@ void CWalletTx::RelayWalletTransaction() } } -set<uint256> CWalletTx::GetConflicts() const +set<uint256> CWalletTx::GetConflicts(bool includeEquivalent) const { set<uint256> result; if (pwallet != NULL) { uint256 myHash = GetHash(); - result = pwallet->GetConflicts(myHash); + result = pwallet->GetConflicts(myHash, includeEquivalent); result.erase(myHash); } return result; |