From a7d3936de8418522dbb161bfef31c234fc6c2503 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Fri, 20 Jan 2017 15:08:14 -0500 Subject: 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() --- src/validationinterface.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'src/validationinterface.h') 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 @@ -36,6 +38,15 @@ protected: virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {} /** 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 CBlockIndex *pindex, const std::vector &); -- cgit v1.2.3 From 0343676ce32ef69b25bada101223b92f92da158a Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 8 Jun 2017 11:05:18 -0400 Subject: Call TransactionRemovedFromMempool in the CScheduler thread This is both good practice (we want to move all such callbacks into a background thread eventually) and prevents a lock inversion when we go to use this in wallet (mempool.cs->cs_wallet and cs_wallet->mempool.cs would otherwise both be used). --- src/validationinterface.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/validationinterface.h') diff --git a/src/validationinterface.h b/src/validationinterface.h index 915c17695e..9b5784ccc3 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -45,6 +45,8 @@ protected: * 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. + * + * Called on a background thread. */ virtual void TransactionRemovedFromMempool(const CTransactionRef &ptx) {} /** -- cgit v1.2.3 From 0b2f42d7376c5f7c1ba1ac5d17a30691989d9159 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 8 Jun 2017 11:13:46 -0400 Subject: Add CallFunctionInQueue to wait on validation interface queue drain --- src/validationinterface.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/validationinterface.h') diff --git a/src/validationinterface.h b/src/validationinterface.h index 9b5784ccc3..1b231e5281 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -6,10 +6,11 @@ #ifndef BITCOIN_VALIDATIONINTERFACE_H #define BITCOIN_VALIDATIONINTERFACE_H -#include - #include "primitives/transaction.h" // CTransaction(Ref) +#include +#include + class CBlock; class CBlockIndex; struct CBlockLocator; @@ -31,6 +32,16 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn); void UnregisterValidationInterface(CValidationInterface* pwalletIn); /** Unregister all wallets from core */ void UnregisterAllValidationInterfaces(); +/** + * Pushes a function to callback onto the notification queue, guaranteeing any + * callbacks generated prior to now are finished when the function is called. + * + * Be very careful blocking on func to be called if any locks are held - + * validation interface clients may not be able to make progress as they often + * wait for things like cs_main, so blocking until func is called with cs_main + * will result in a deadlock (that DEBUG_LOCKORDER will miss). + */ +void CallFunctionInValidationInterfaceQueue(std::function func); class CValidationInterface { protected: @@ -86,6 +97,7 @@ private: friend void ::RegisterValidationInterface(CValidationInterface*); friend void ::UnregisterValidationInterface(CValidationInterface*); friend void ::UnregisterAllValidationInterfaces(); + friend void ::CallFunctionInValidationInterfaceQueue(std::function func); void MempoolEntryRemoved(CTransactionRef tx, MemPoolRemovalReason reason); -- cgit v1.2.3 From e545dedf72bff2bd41c93c93eb576929fce37112 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 8 Jun 2017 11:08:53 -0400 Subject: Also call other wallet notify callbacks in scheduler thread This runs Block{Connected,Disconnected}, SetBestChain, Inventory, and TransactionAddedToMempool on the background scheduler thread. Of those, only BlockConnected is used outside of Wallet/ZMQ, and is used only for orphan transaction removal in net_processing, something which does not need to be synchronous with anything else. This partially reverts #9583, re-enabling some of the gains from #7946. This does not, however, re-enable the gains achieved by repeatedly releasing cs_main between each transaction processed. --- src/validationinterface.h | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'src/validationinterface.h') diff --git a/src/validationinterface.h b/src/validationinterface.h index 1b231e5281..9b5ac2ac23 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -47,7 +47,11 @@ class CValidationInterface { protected: /** Notifies listeners of updated block chain tip */ 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. + * + * Called on a background thread. + */ virtual void TransactionAddedToMempool(const CTransactionRef &ptxn) {} /** * Notifies listeners of a transaction leaving mempool. @@ -63,13 +67,27 @@ protected: /** * Notifies listeners of a block being connected. * Provides a vector of transactions evicted from the mempool as a result. + * + * Called on a background thread. */ virtual void BlockConnected(const std::shared_ptr &block, const CBlockIndex *pindex, const std::vector &txnConflicted) {} - /** Notifies listeners of a block being disconnected */ + /** + * Notifies listeners of a block being disconnected + * + * Called on a background thread. + */ virtual void BlockDisconnected(const std::shared_ptr &block) {} - /** Notifies listeners of the new active block chain on-disk. */ + /** + * Notifies listeners of the new active block chain on-disk. + * + * Called on a background thread. + */ virtual void SetBestChain(const CBlockLocator &locator) {} - /** Notifies listeners about an inventory item being seen on the network. */ + /** + * Notifies listeners about an inventory item being seen on the network. + * + * Called on a background thread. + */ virtual void Inventory(const uint256 &hash) {} /** Tells listeners to broadcast their data. */ virtual void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) {} @@ -116,7 +134,7 @@ public: void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload); void TransactionAddedToMempool(const CTransactionRef &); - void BlockConnected(const std::shared_ptr &, const CBlockIndex *pindex, const std::vector &); + void BlockConnected(const std::shared_ptr &, const CBlockIndex *pindex, const std::shared_ptr> &); void BlockDisconnected(const std::shared_ptr &); void SetBestChain(const CBlockLocator &); void Inventory(const uint256 &); -- cgit v1.2.3 From 3ea8b75281edc60078423bd5d277cd2a84aa5d33 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Sat, 30 Sep 2017 23:49:59 -0400 Subject: Give ZMQ consistent order with UpdatedBlockTip on scheduler thread Note that UpdatedBlockTip is also used in net_processing to announce new blocks to peers. As this may need additional review, this change is included in its own commit. --- src/validationinterface.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/validationinterface.h') diff --git a/src/validationinterface.h b/src/validationinterface.h index 9b5ac2ac23..1494c6dc21 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -45,7 +45,11 @@ void CallFunctionInValidationInterfaceQueue(std::function func); class CValidationInterface { protected: - /** Notifies listeners of updated block chain tip */ + /** + * Notifies listeners of updated block chain tip + * + * Called on a background thread. + */ virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {} /** * Notifies listeners of a transaction having been added to mempool. -- cgit v1.2.3