aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/wallet.cpp
diff options
context:
space:
mode:
authorMatt Corallo <git@bluematt.me>2017-03-29 21:12:42 -0400
committerMatt Corallo <git@bluematt.me>2017-04-07 11:53:43 +0200
commit461e49fee2935b1eb4d4ea7bae3023e655c0a6d8 (patch)
tree243e76a8c99a0059ee867976603a3426f5f8bf3c /src/wallet/wallet.cpp
parentf4043349106067de66a3312ed3485149bdb71247 (diff)
downloadbitcoin-461e49fee2935b1eb4d4ea7bae3023e655c0a6d8.tar.xz
SyncTransaction->TxAddedToMempool/BlockConnected/Disconnected
This simplifies fixing the wallet-returns-stale-info issue as we can now hold cs_wallet across an entire block instead of only per-tx (though we only actually do so in the next commit). This change also removes the NOT_IN_BLOCK constant in favor of only passing the CBlockIndex* parameter to SyncTransactions when a new block is being connected, instead of also when a block is being disconnected. This change adds a parameter to BlockConnectedDisconnected which lists the transactions which were removed from mempool due to confliction as a result of this operation. While its somewhat of a shame to make block-validation-logic generate a list of mempool changes to be included in its generated callbacks, fixing this isnt too hard. Further in this change-set, CValidationInterface starts listening to mempool directly, placing it in the middle and giving it a bit of logic to know how to route notifications from block-validation, mempool, etc (though not listening for conflicted-removals yet).
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r--src/wallet/wallet.cpp39
1 files changed, 35 insertions, 4 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 55d81daab4..2b66faf687 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1116,11 +1116,10 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
}
}
-void CWallet::SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex, int posInBlock)
-{
- LOCK2(cs_main, cs_wallet);
+void CWallet::SyncTransaction(const CTransactionRef& ptx, const CBlockIndex *pindexBlockConnected, int posInBlock) {
+ const CTransaction& tx = *ptx;
- if (!AddToWalletIfInvolvingMe(tx, pindex, posInBlock, true))
+ if (!AddToWalletIfInvolvingMe(tx, pindexBlockConnected, posInBlock, true))
return; // Not one of ours
// If a transaction changes 'conflicted' state, that changes the balance
@@ -1133,6 +1132,38 @@ void CWallet::SyncTransaction(const CTransaction& tx, const CBlockIndex *pindex,
}
}
+void CWallet::TransactionAddedToMempool(const CTransactionRef& ptx) {
+ LOCK2(cs_main, cs_wallet);
+ SyncTransaction(ptx, NULL, -1);
+}
+
+void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) {
+ // TODO: Tempoarily ensure that mempool removals are notified before
+ // connected transactions. This shouldn't matter, but the abandoned
+ // state of transactions in our wallet is currently cleared when we
+ // receive another notification and there is a race condition where
+ // notification of a connected conflict might cause an outside process
+ // to abandon a transaction and then have it inadvertantly cleared by
+ // the notification that the conflicted transaction was evicted.
+
+ for (const CTransactionRef& ptx : vtxConflicted) {
+ LOCK2(cs_main, cs_wallet);
+ SyncTransaction(ptx, NULL, -1);
+ }
+ for (size_t i = 0; i < pblock->vtx.size(); i++) {
+ LOCK2(cs_main, cs_wallet);
+ SyncTransaction(pblock->vtx[i], pindex, i);
+ }
+}
+
+void CWallet::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) {
+ for (const CTransactionRef& ptx : pblock->vtx) {
+ LOCK2(cs_main, cs_wallet);
+ SyncTransaction(ptx, NULL, -1);
+ }
+}
+
+
isminetype CWallet::IsMine(const CTxIn &txin) const
{