From 3278c5c134c4e95d8df7ec76c3335a8b9d08676a Mon Sep 17 00:00:00 2001 From: janko33bd Date: Fri, 23 Jun 2017 20:56:54 +0200 Subject: [PATCH] ppcoin: disable transaction (only for coinstake) --- src/wallet/wallet.cpp | 67 ++++++++++++++++++++++++++++++++++++++++++- src/wallet/wallet.h | 5 ++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index ddbbd69f0..223f0aeab 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -486,6 +486,23 @@ void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid) } +void CWallet::RemoveFromSpends(const COutPoint& outpoint, const uint256& wtxid) +{ + pair range; + range = mapTxSpends.equal_range(outpoint); + TxSpends::iterator it = range.first; + for(; it != range.second; ++ it) + { + if(it->second == wtxid) + { + mapTxSpends.erase(it); + break; + } + } + range = mapTxSpends.equal_range(outpoint); + SyncMetaData(range); +} + void CWallet::AddToSpends(const uint256& wtxid) { assert(mapWallet.count(wtxid)); @@ -497,6 +514,17 @@ void CWallet::AddToSpends(const uint256& wtxid) AddToSpends(txin.prevout, wtxid); } +void CWallet::RemoveFromSpends(const uint256& wtxid) +{ + assert(mapWallet.count(wtxid)); + CWalletTx& thisTx = mapWallet[wtxid]; + if (thisTx.IsCoinBase()) // Coinbases don't spend anything! + return; + + BOOST_FOREACH(const CTxIn& txin, thisTx.vin) + RemoveFromSpends(txin.prevout, wtxid); +} + void CWallet::AvailableCoinsForStaking(std::vector& vCoins) const { vCoins.clear(); @@ -1204,7 +1232,20 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock) { - LOCK2(cs_main, cs_wallet); + + + + LOCK2(cs_main, cs_wallet); + + if (!pblock) { + // wallets need to refund inputs when disconnecting coinstake + if (tx.IsCoinStake()) { + if (IsFromMe(tx)) { + DisableTransaction(tx); + return; + } + } + } if (!AddToWalletIfInvolvingMe(tx, pblock, true)) return; // Not one of ours @@ -3054,6 +3095,30 @@ std::set CWallet::GetAccountAddresses(const std::string& strAcco return result; } +// ppcoin: disable transaction (only for coinstake) +void CWallet::DisableTransaction(const CTransaction &tx) +{ + if (!tx.IsCoinStake() || !IsFromMe(tx)) + return; // only disconnecting coinstake requires marking input unspent + + LOCK(cs_wallet); + uint256 hash = tx.GetHash(); + if(AbandonTransaction(hash)) + { + RemoveFromSpends(hash); + set setCoins; + BOOST_FOREACH(const CTxIn& txin, tx.vin) + { + CWalletTx &coin = mapWallet[txin.prevout.hash]; + coin.BindWallet(this); + NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED); + } + CWalletTx& wtx = mapWallet[hash]; + wtx.BindWallet(this); + NotifyTransactionChanged(this, hash, CT_DELETED); + } +} + bool CReserveKey::GetReservedKey(CPubKey& pubkey) { if (nIndex == -1) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 154c2f5a0..19cfcc786 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -499,7 +499,10 @@ private: typedef std::multimap TxSpends; TxSpends mapTxSpends; void AddToSpends(const COutPoint& outpoint, const uint256& wtxid); + void RemoveFromSpends(const COutPoint& outpoint, const uint256& wtxid); void AddToSpends(const uint256& wtxid); + void RemoveFromSpends(const uint256& wtxid); + /* Mark a transaction (and its in-wallet descendants) as conflicting with a particular block. */ void MarkConflicted(const uint256& hashBlock, const uint256& hashTx); @@ -767,6 +770,8 @@ public: //! get the current wallet format (the oldest client version guaranteed to understand this wallet) int GetVersion() { LOCK(cs_wallet); return nWalletVersion; } + void DisableTransaction(const CTransaction &tx); + //! Get wallet transactions that conflict with given transaction (spend same outputs) std::set GetConflicts(const uint256& txid) const;