Add a CValidationInterface::TransactionRemovedFromMempool

This is currently unused, but will by used by wallet to cache when
transactions are in the mempool, obviating the need for calls to
mempool from CWalletTx::InMempool()
This commit is contained in:
Matt Corallo 2017-01-20 15:08:14 -05:00
parent 326a5652e0
commit a7d3936de8
4 changed files with 42 additions and 0 deletions

View file

@ -265,6 +265,7 @@ void Shutdown()
#endif #endif
UnregisterAllValidationInterfaces(); UnregisterAllValidationInterfaces();
GetMainSignals().UnregisterBackgroundSignalScheduler(); GetMainSignals().UnregisterBackgroundSignalScheduler();
GetMainSignals().UnregisterWithMempoolSignals(mempool);
#ifdef ENABLE_WALLET #ifdef ENABLE_WALLET
CloseWallets(); CloseWallets();
#endif #endif
@ -1240,6 +1241,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
threadGroup.create_thread(boost::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop)); threadGroup.create_thread(boost::bind(&TraceThread<CScheduler::Function>, "scheduler", serviceLoop));
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
GetMainSignals().RegisterWithMempoolSignals(mempool);
/* Start the RPC server already. It will be started in "warmup" mode /* Start the RPC server already. It will be started in "warmup" mode
* and not really process calls already (but it will signify connections * and not really process calls already (but it will signify connections

View file

@ -513,6 +513,9 @@ public:
// to track size/count of descendant transactions. First version of // to track size/count of descendant transactions. First version of
// addUnchecked can be used to have it call CalculateMemPoolAncestors(), and // addUnchecked can be used to have it call CalculateMemPoolAncestors(), and
// then invoke the second version. // 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, bool validFeeEstimate = true);
bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate = true); bool addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate = true);

View file

@ -9,6 +9,7 @@
#include "primitives/block.h" #include "primitives/block.h"
#include "scheduler.h" #include "scheduler.h"
#include "sync.h" #include "sync.h"
#include "txmempool.h"
#include "util.h" #include "util.h"
#include <list> #include <list>
@ -21,6 +22,7 @@ struct MainSignalsInstance {
boost::signals2::signal<void (const CTransactionRef &)> TransactionAddedToMempool; 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> &, const CBlockIndex *pindex, const std::vector<CTransactionRef>&)> BlockConnected;
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &)> BlockDisconnected; 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 CBlockLocator &)> SetBestChain;
boost::signals2::signal<void (const uint256 &)> Inventory; boost::signals2::signal<void (const uint256 &)> Inventory;
boost::signals2::signal<void (int64_t nBestBlockTime, CConnman* connman)> Broadcast; boost::signals2::signal<void (int64_t nBestBlockTime, CConnman* connman)> Broadcast;
@ -50,6 +52,14 @@ void CMainSignals::FlushBackgroundCallbacks() {
m_internals->m_schedulerClient.EmptyQueue(); 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() CMainSignals& GetMainSignals()
{ {
return g_signals; 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->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->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->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->SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
g_signals.m_internals->Inventory.connect(boost::bind(&CValidationInterface::Inventory, 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)); 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->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->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->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->UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1, _2, _3));
g_signals.m_internals->NewPoWValidBlock.disconnect(boost::bind(&CValidationInterface::NewPoWValidBlock, pwalletIn, _1, _2)); 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->TransactionAddedToMempool.disconnect_all_slots();
g_signals.m_internals->BlockConnected.disconnect_all_slots(); g_signals.m_internals->BlockConnected.disconnect_all_slots();
g_signals.m_internals->BlockDisconnected.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->UpdatedBlockTip.disconnect_all_slots();
g_signals.m_internals->NewPoWValidBlock.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) { void CMainSignals::UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {
m_internals->UpdatedBlockTip(pindexNew, pindexFork, fInitialDownload); m_internals->UpdatedBlockTip(pindexNew, pindexFork, fInitialDownload);
} }

View file

@ -20,6 +20,8 @@ class CValidationInterface;
class CValidationState; class CValidationState;
class uint256; class uint256;
class CScheduler; class CScheduler;
class CTxMemPool;
enum class MemPoolRemovalReason;
// These functions dispatch to one or all registered wallets // These functions dispatch to one or all registered wallets
@ -36,6 +38,15 @@ protected:
virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {} virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {}
/** Notifies listeners of a transaction having been added to mempool. */ /** Notifies listeners of a transaction having been added to mempool. */
virtual void TransactionAddedToMempool(const CTransactionRef &ptxn) {} 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. * Notifies listeners of a block being connected.
* Provides a vector of transactions evicted from the mempool as a result. * Provides a vector of transactions evicted from the mempool as a result.
@ -74,6 +85,8 @@ private:
friend void ::UnregisterValidationInterface(CValidationInterface*); friend void ::UnregisterValidationInterface(CValidationInterface*);
friend void ::UnregisterAllValidationInterfaces(); friend void ::UnregisterAllValidationInterfaces();
void MempoolEntryRemoved(CTransactionRef tx, MemPoolRemovalReason reason);
public: public:
/** Register a CScheduler to give callbacks which should run in the background (may only be called once) */ /** Register a CScheduler to give callbacks which should run in the background (may only be called once) */
void RegisterBackgroundSignalScheduler(CScheduler& scheduler); void RegisterBackgroundSignalScheduler(CScheduler& scheduler);
@ -82,6 +95,11 @@ public:
/** Call any remaining callbacks on the calling thread */ /** Call any remaining callbacks on the calling thread */
void FlushBackgroundCallbacks(); 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 UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
void TransactionAddedToMempool(const CTransactionRef &); void TransactionAddedToMempool(const CTransactionRef &);
void BlockConnected(const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::vector<CTransactionRef> &); void BlockConnected(const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::vector<CTransactionRef> &);