aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/init.cpp2
-rw-r--r--src/txmempool.h3
-rw-r--r--src/validationinterface.cpp19
-rw-r--r--src/validationinterface.h18
4 files changed, 42 insertions, 0 deletions
diff --git a/src/init.cpp b/src/init.cpp
index f63ad7f5d3..499edb374c 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -265,6 +265,7 @@ void Shutdown()
#endif
UnregisterAllValidationInterfaces();
GetMainSignals().UnregisterBackgroundSignalScheduler();
+ GetMainSignals().UnregisterWithMempoolSignals(mempool);
#ifdef ENABLE_WALLET
CloseWallets();
#endif
@@ -1240,6 +1241,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
threadGroup.create_thread(boost::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
+ GetMainSignals().RegisterWithMempoolSignals(mempool);
/* Start the RPC server already. It will be started in "warmup" mode
* and not really process calls already (but it will signify connections
diff --git a/src/txmempool.h b/src/txmempool.h
index 929d223588..a4d6f6a310 100644
--- a/src/txmempool.h
+++ b/src/txmempool.h
@@ -513,6 +513,9 @@ public:
// to track size/count of descendant transactions. First version of
// addUnchecked can be used to have it call CalculateMemPoolAncestors(), and
// then invoke the second version.
+ // Note that addUnchecked is ONLY called from ATMP outside of tests
+ // and any other callers may break wallet's in-mempool tracking (due to
+ // lack of CValidationInterface::TransactionAddedToMempool callbacks).
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, bool validFeeEstimate = true);
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate = true);
diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp
index 281bc04b0a..24f2b96c78 100644
--- a/src/validationinterface.cpp
+++ b/src/validationinterface.cpp
@@ -9,6 +9,7 @@
#include "primitives/block.h"
#include "scheduler.h"
#include "sync.h"
+#include "txmempool.h"
#include "util.h"
#include <list>
@@ -21,6 +22,7 @@ struct MainSignalsInstance {
boost::signals2::signal<void (const CTransactionRef &)> TransactionAddedToMempool;
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::vector<CTransactionRef>&)> BlockConnected;
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &)> BlockDisconnected;
+ boost::signals2::signal<void (const CTransactionRef &)> TransactionRemovedFromMempool;
boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
boost::signals2::signal<void (const uint256 &)> Inventory;
boost::signals2::signal<void (int64_t nBestBlockTime, CConnman* connman)> Broadcast;
@@ -50,6 +52,14 @@ void CMainSignals::FlushBackgroundCallbacks() {
m_internals->m_schedulerClient.EmptyQueue();
}
+void CMainSignals::RegisterWithMempoolSignals(CTxMemPool& pool) {
+ pool.NotifyEntryRemoved.connect(boost::bind(&CMainSignals::MempoolEntryRemoved, this, _1, _2));
+}
+
+void CMainSignals::UnregisterWithMempoolSignals(CTxMemPool& pool) {
+ pool.NotifyEntryRemoved.disconnect(boost::bind(&CMainSignals::MempoolEntryRemoved, this, _1, _2));
+}
+
CMainSignals& GetMainSignals()
{
return g_signals;
@@ -60,6 +70,7 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.m_internals->TransactionAddedToMempool.connect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1));
g_signals.m_internals->BlockConnected.connect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3));
g_signals.m_internals->BlockDisconnected.connect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1));
+ g_signals.m_internals->TransactionRemovedFromMempool.connect(boost::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, _1));
g_signals.m_internals->SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
g_signals.m_internals->Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
g_signals.m_internals->Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2));
@@ -75,6 +86,7 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
g_signals.m_internals->TransactionAddedToMempool.disconnect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1));
g_signals.m_internals->BlockConnected.disconnect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3));
g_signals.m_internals->BlockDisconnected.disconnect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1));
+ g_signals.m_internals->TransactionRemovedFromMempool.disconnect(boost::bind(&CValidationInterface::TransactionRemovedFromMempool, pwalletIn, _1));
g_signals.m_internals->UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
g_signals.m_internals->NewPoWValidBlock.disconnect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2));
}
@@ -87,10 +99,17 @@ void UnregisterAllValidationInterfaces() {
g_signals.m_internals->TransactionAddedToMempool.disconnect_all_slots();
g_signals.m_internals->BlockConnected.disconnect_all_slots();
g_signals.m_internals->BlockDisconnected.disconnect_all_slots();
+ g_signals.m_internals->TransactionRemovedFromMempool.disconnect_all_slots();
g_signals.m_internals->UpdatedBlockTip.disconnect_all_slots();
g_signals.m_internals->NewPoWValidBlock.disconnect_all_slots();
}
+void CMainSignals::MempoolEntryRemoved(CTransactionRef ptx, MemPoolRemovalReason reason) {
+ if (reason != MemPoolRemovalReason::BLOCK && reason != MemPoolRemovalReason::CONFLICT) {
+ m_internals->TransactionRemovedFromMempool(ptx);
+ }
+}
+
void CMainSignals::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {
m_internals->UpdatedBlockTip(pindexNew, pindexFork, fInitialDownload);
}
diff --git a/src/validationinterface.h b/src/validationinterface.h
index d6da2bc1fd..915c17695e 100644
--- a/src/validationinterface.h
+++ b/src/validationinterface.h
@@ -20,6 +20,8 @@ class CValidationInterface;
class CValidationState;
class uint256;
class CScheduler;
+class CTxMemPool;
+enum class MemPoolRemovalReason;
// These functions dispatch to one or all registered wallets
@@ -37,6 +39,15 @@ protected:
/** Notifies listeners of a transaction having been added to mempool. */
virtual void TransactionAddedToMempool(const CTransactionRef &ptxn) {}
/**
+ * Notifies listeners of a transaction leaving mempool.
+ *
+ * This only fires for transactions which leave mempool because of expiry,
+ * size limiting, reorg (changes in lock times/coinbase maturity), or
+ * replacement. This does not include any transactions which are included
+ * in BlockConnectedDisconnected either in block->vtx or in txnConflicted.
+ */
+ virtual void TransactionRemovedFromMempool(const CTransactionRef &ptx) {}
+ /**
* Notifies listeners of a block being connected.
* Provides a vector of transactions evicted from the mempool as a result.
*/
@@ -74,6 +85,8 @@ private:
friend void ::UnregisterValidationInterface(CValidationInterface*);
friend void ::UnregisterAllValidationInterfaces();
+ void MempoolEntryRemoved(CTransactionRef tx, MemPoolRemovalReason reason);
+
public:
/** Register a CScheduler to give callbacks which should run in the background (may only be called once) */
void RegisterBackgroundSignalScheduler(CScheduler& scheduler);
@@ -82,6 +95,11 @@ public:
/** Call any remaining callbacks on the calling thread */
void FlushBackgroundCallbacks();
+ /** Register with mempool to call TransactionRemovedFromMempool callbacks */
+ void RegisterWithMempoolSignals(CTxMemPool& pool);
+ /** Unregister with mempool */
+ void UnregisterWithMempoolSignals(CTxMemPool& pool);
+
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
void TransactionAddedToMempool(const CTransactionRef &);
void BlockConnected(const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::vector<CTransactionRef> &);