diff --git a/src/init.cpp b/src/init.cpp index 28044ab55243..66f858d86c93 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -265,6 +265,19 @@ void PrepareShutdown() fFeeEstimatesInitialized = false; } + // FlushStateToDisk generates a SetBestChain callback, which we should avoid missing + FlushStateToDisk(); + + // After there are no more peers/RPC left to give us new data which may generate + // CValidationInterface callbacks, flush them... + GetMainSignals().FlushBackgroundCallbacks(); + + // Any future callbacks will be dropped. This should absolutely be safe - if + // missing a callback results in an unrecoverable situation, unclean shutdown + // would too. The only reason to do the above flushes is to let the wallet catch + // up with our current chain to avoid any strange pruning edge cases and make + // next startup faster by avoiding rescan. + { LOCK(cs_main); if (pcoinsTip != NULL) { @@ -301,6 +314,7 @@ void PrepareShutdown() // Disconnect all slots UnregisterAllValidationInterfaces(); + GetMainSignals().UnregisterBackgroundSignalScheduler(); #ifndef WIN32 try { @@ -1243,6 +1257,8 @@ bool AppInitMain() CScheduler::Function serviceLoop = std::bind(&CScheduler::serviceQueue, &scheduler); threadGroup.create_thread(std::bind(&TraceThread, "scheduler", serviceLoop)); + GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); + // Initialize Sapling circuit parameters LoadSaplingParams(); diff --git a/src/scheduler.cpp b/src/scheduler.cpp index bb671645b360..0232ad2794ef 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -120,3 +120,69 @@ size_t CScheduler::getQueueInfo(boost::chrono::system_clock::time_point &first, } return result; } + +bool CScheduler::AreThreadsServicingQueue() const { + boost::unique_lock lock(newTaskMutex); + return nThreadsServicingQueue; +} + +void SingleThreadedSchedulerClient::MaybeScheduleProcessQueue() { + { + LOCK(m_cs_callbacks_pending); + // Try to avoid scheduling too many copies here, but if we + // accidentally have two ProcessQueue's scheduled at once its + // not a big deal. + if (m_are_callbacks_running) return; + if (m_callbacks_pending.empty()) return; + } + m_pscheduler->schedule(std::bind(&SingleThreadedSchedulerClient::ProcessQueue, this)); +} + +void SingleThreadedSchedulerClient::ProcessQueue() { + std::function callback; + { + LOCK(m_cs_callbacks_pending); + if (m_are_callbacks_running) return; + if (m_callbacks_pending.empty()) return; + m_are_callbacks_running = true; + + callback = std::move(m_callbacks_pending.front()); + m_callbacks_pending.pop_front(); + } + + // RAII the setting of fCallbacksRunning and calling MaybeScheduleProcessQueue + // to ensure both happen safely even if callback() throws. + struct RAIICallbacksRunning { + SingleThreadedSchedulerClient* instance; + explicit RAIICallbacksRunning(SingleThreadedSchedulerClient* _instance) : instance(_instance) {} + ~RAIICallbacksRunning() { + { + LOCK(instance->m_cs_callbacks_pending); + instance->m_are_callbacks_running = false; + } + instance->MaybeScheduleProcessQueue(); + } + } raiicallbacksrunning(this); + + callback(); +} + +void SingleThreadedSchedulerClient::AddToProcessQueue(std::function func) { + assert(m_pscheduler); + + { + LOCK(m_cs_callbacks_pending); + m_callbacks_pending.emplace_back(std::move(func)); + } + MaybeScheduleProcessQueue(); +} + +void SingleThreadedSchedulerClient::EmptyQueue() { + assert(!m_pscheduler->AreThreadsServicingQueue()); + bool should_continue = true; + while (should_continue) { + ProcessQueue(); + LOCK(m_cs_callbacks_pending); + should_continue = !m_callbacks_pending.empty(); + } +} diff --git a/src/scheduler.h b/src/scheduler.h index 9f1b703dd8f0..71ca40f4fb83 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -15,6 +15,8 @@ #include #include +#include "sync.h" + // // Simple class for background tasks that should be run // periodically or once "after a while" @@ -42,7 +44,7 @@ class CScheduler typedef std::function Function; // Call func at/after time t - void schedule(Function f, boost::chrono::system_clock::time_point t); + void schedule(Function f, boost::chrono::system_clock::time_point t=boost::chrono::system_clock::now()); // Convenience method: call f once deltaMilliSeconds from now void scheduleFromNow(Function f, int64_t deltaMilliSeconds); @@ -70,6 +72,9 @@ class CScheduler size_t getQueueInfo(boost::chrono::system_clock::time_point &first, boost::chrono::system_clock::time_point &last) const; + // Returns true if there are threads actively running in serviceQueue() + bool AreThreadsServicingQueue() const; + private: std::multimap taskQueue; boost::condition_variable newTaskScheduled; @@ -77,7 +82,33 @@ class CScheduler int nThreadsServicingQueue; bool stopRequested; bool stopWhenEmpty; - bool shouldStop() { return stopRequested || (stopWhenEmpty && taskQueue.empty()); } + bool shouldStop() const { return stopRequested || (stopWhenEmpty && taskQueue.empty()); } +}; + +/** + * Class used by CScheduler clients which may schedule multiple jobs + * which are required to be run serially. Does not require such jobs + * to be executed on the same thread, but no two jobs will be executed + * at the same time. + */ +class SingleThreadedSchedulerClient { +private: + CScheduler *m_pscheduler; + + RecursiveMutex m_cs_callbacks_pending; + std::list> m_callbacks_pending; + bool m_are_callbacks_running = false; + + void MaybeScheduleProcessQueue(); + void ProcessQueue(); + +public: + explicit SingleThreadedSchedulerClient(CScheduler *pschedulerIn) : m_pscheduler(pschedulerIn) {} + void AddToProcessQueue(std::function func); + + // Processes all remaining queue members on the calling thread, blocking until queue is empty + // Must be called after the CScheduler has no remaining processing threads! + void EmptyQueue(); }; #endif diff --git a/src/test/test_pivx.cpp b/src/test/test_pivx.cpp index d803be76aace..8537114b1285 100644 --- a/src/test/test_pivx.cpp +++ b/src/test/test_pivx.cpp @@ -53,6 +53,12 @@ TestingSetup::TestingSetup() pathTemp = GetTempPath() / strprintf("test_pivx_%lu_%i", (unsigned long)GetTime(), (int)(InsecureRandRange(100000))); fs::create_directories(pathTemp); gArgs.ForceSetArg("-datadir", pathTemp.string()); + + // Note that because we don't bother running a scheduler thread here, + // callbacks via CValidationInterface are unreliable, but that's OK, + // our unit tests aren't testing multiple parts of the code at once. + GetMainSignals().RegisterBackgroundSignalScheduler(scheduler); + // Ideally we'd move all the RPC tests to the functional testing framework // instead of unit tests, but for now we need these here. RegisterAllCoreRPCCommands(tableRPC); @@ -80,6 +86,8 @@ TestingSetup::~TestingSetup() UnregisterNodeSignals(GetNodeSignals()); threadGroup.interrupt_all(); threadGroup.join_all(); + GetMainSignals().FlushBackgroundCallbacks(); + GetMainSignals().UnregisterBackgroundSignalScheduler(); UnloadBlockIndex(); delete pcoinsTip; delete pcoinsdbview; diff --git a/src/test/test_pivx.h b/src/test/test_pivx.h index b56e18a80376..d22da8ecd1bd 100644 --- a/src/test/test_pivx.h +++ b/src/test/test_pivx.h @@ -6,6 +6,7 @@ #define PIVX_TEST_TEST_PIVX_H #include "fs.h" +#include "scheduler.h" #include "txdb.h" #include @@ -48,6 +49,7 @@ struct TestingSetup: public BasicTestingSetup { fs::path pathTemp; boost::thread_group threadGroup; CConnman* connman; + CScheduler scheduler; ECCVerifyHandle globalVerifyHandle; TestingSetup(); diff --git a/src/validation.cpp b/src/validation.cpp index b9dcc4459a73..8537b51469b1 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1388,7 +1388,10 @@ static int64_t nTimeIndex = 0; static int64_t nTimeCallbacks = 0; static int64_t nTimeTotal = 0; -bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck, bool fAlreadyChecked) +/** Apply the effects of this block (with given index) on the UTXO set represented by coins. + * Validity checks that depend on the UTXO set are also done; ConnectBlock() + * can fail if those validity checks fail (among other reasons). */ +static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck = false, bool fAlreadyChecked = false) { AssertLockHeld(cs_main); // Check it again in case a previous version let a bad block in @@ -1704,11 +1707,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin nTimeIndex += nTime3 - nTime2; LogPrint(BCLog::BENCH, " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001); - // Watch for changes to the previous coinbase transaction. - static uint256 hashPrevBestCoinBase; - GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase); - hashPrevBestCoinBase = block.vtx[0]->GetHash(); - int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3; LogPrint(BCLog::BENCH, " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001); diff --git a/src/validation.h b/src/validation.h index 6f6804ac39c3..be6d571c935c 100644 --- a/src/validation.h +++ b/src/validation.h @@ -322,9 +322,6 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); /** Functions for validating blocks and updating the block tree */ -/** Apply the effects of this block (with given index) on the UTXO set represented by coins */ -bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck, bool fAlreadyChecked = false); - /** Context-independent validity checks */ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true, bool fCheckSig = true); bool CheckWork(const CBlock& block, const CBlockIndex* const pindexPrev); diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index 9fa5029fe023..d38e04bf1f42 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -5,7 +5,9 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "validationinterface.h" +#include "scheduler.h" +#include #include #include @@ -14,8 +16,6 @@ struct ValidationInterfaceConnections { boost::signals2::scoped_connection TransactionAddedToMempool; boost::signals2::scoped_connection BlockConnected; boost::signals2::scoped_connection BlockDisconnected; - boost::signals2::scoped_connection NotifyTransactionLock; - boost::signals2::scoped_connection UpdatedTransaction; boost::signals2::scoped_connection SetBestChain; boost::signals2::scoped_connection Broadcast; boost::signals2::scoped_connection BlockChecked; @@ -34,10 +34,6 @@ struct MainSignalsInstance { boost::signals2::signal &, const CBlockIndex *pindex, const std::vector &)> BlockConnected; /** Notifies listeners of a block being disconnected */ boost::signals2::signal &, int nBlockHeight)> BlockDisconnected; - /** Notifies listeners of an updated transaction lock without new data. */ - boost::signals2::signal NotifyTransactionLock; - /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ - boost::signals2::signal UpdatedTransaction; /** Notifies listeners of a new active block chain. */ boost::signals2::signal SetBestChain; /** Tells listeners to broadcast their data. */ @@ -46,12 +42,30 @@ struct MainSignalsInstance { boost::signals2::signal BlockChecked; std::unordered_map m_connMainSignals; + + // We are not allowed to assume the scheduler only runs in one thread, + // but must ensure all callbacks happen in-order, so we end up creating + // our own queue here :( + SingleThreadedSchedulerClient m_schedulerClient; + + explicit MainSignalsInstance(CScheduler *pscheduler) : m_schedulerClient(pscheduler) {} }; static CMainSignals g_signals; -CMainSignals::CMainSignals() { - m_internals.reset(new MainSignalsInstance()); +void CMainSignals::RegisterBackgroundSignalScheduler(CScheduler& scheduler) { + assert(!m_internals); + m_internals.reset(new MainSignalsInstance(&scheduler)); +} + +void CMainSignals::UnregisterBackgroundSignalScheduler() { + m_internals.reset(nullptr); +} + +void CMainSignals::FlushBackgroundCallbacks() { + if (m_internals) { + m_internals->m_schedulerClient.EmptyQueue(); + } } CMainSignals& GetMainSignals() @@ -66,8 +80,6 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) conns.TransactionAddedToMempool = g_signals.m_internals->TransactionAddedToMempool.connect(std::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, std::placeholders::_1)); conns.BlockConnected = g_signals.m_internals->BlockConnected.connect(std::bind(&CValidationInterface::BlockConnected, pwalletIn, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); conns.BlockDisconnected = g_signals.m_internals->BlockDisconnected.connect(std::bind(&CValidationInterface::BlockDisconnected, pwalletIn, std::placeholders::_1, std::placeholders::_2)); - conns.NotifyTransactionLock = g_signals.m_internals->NotifyTransactionLock.connect(std::bind(&CValidationInterface::NotifyTransactionLock, pwalletIn, std::placeholders::_1)); - conns.UpdatedTransaction = g_signals.m_internals->UpdatedTransaction.connect(std::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, std::placeholders::_1)); conns.SetBestChain = g_signals.m_internals->SetBestChain.connect(std::bind(&CValidationInterface::SetBestChain, pwalletIn, std::placeholders::_1)); conns.Broadcast = g_signals.m_internals->Broadcast.connect(std::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, std::placeholders::_1)); conns.BlockChecked = g_signals.m_internals->BlockChecked.connect(std::bind(&CValidationInterface::BlockChecked, pwalletIn, std::placeholders::_1, std::placeholders::_2)); @@ -104,14 +116,6 @@ void CMainSignals::BlockDisconnected(const std::shared_ptr &block, m_internals->BlockDisconnected(block, nBlockHeight); } -void CMainSignals::NotifyTransactionLock(const CTransaction& tx) { - m_internals->NotifyTransactionLock(tx); -} - -void CMainSignals::UpdatedTransaction(const uint256& hash) { - m_internals->UpdatedTransaction(hash); -} - void CMainSignals::SetBestChain(const CBlockLocator& locator) { m_internals->SetBestChain(locator); } diff --git a/src/validationinterface.h b/src/validationinterface.h index af980450a250..0a4343070426 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -18,6 +18,7 @@ class CConnman; class CValidationInterface; class CValidationState; class uint256; +class CScheduler; // These functions dispatch to one or all registered wallets @@ -29,16 +30,16 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn); void UnregisterAllValidationInterfaces(); class CValidationInterface { +public: + virtual ~CValidationInterface() = default; protected: /** Notifies listeners of updated block chain tip */ virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {} virtual void TransactionAddedToMempool(const CTransactionRef &ptxn) {} virtual void BlockConnected(const std::shared_ptr &block, const CBlockIndex *pindex, const std::vector &txnConflicted) {} virtual void BlockDisconnected(const std::shared_ptr &block, int nBlockHeight) {} - virtual void NotifyTransactionLock(const CTransaction &tx) {} /** Notifies listeners of the new active block chain on-disk. */ virtual void SetBestChain(const CBlockLocator &locator) {} - virtual bool UpdatedTransaction(const uint256 &hash) { return false;} /** Tells listeners to broadcast their data. */ virtual void ResendWalletTransactions(CConnman* connman) {} virtual void BlockChecked(const CBlock&, const CValidationState&) {} @@ -55,15 +56,19 @@ class CMainSignals { friend void ::RegisterValidationInterface(CValidationInterface*); friend void ::UnregisterValidationInterface(CValidationInterface*); friend void ::UnregisterAllValidationInterfaces(); + public: - CMainSignals(); + /** Register a CScheduler to give callbacks which should run in the background (may only be called once) */ + void RegisterBackgroundSignalScheduler(CScheduler& scheduler); + /** Unregister a CScheduler to give callbacks which should run in the background - these callbacks will now be dropped! */ + void UnregisterBackgroundSignalScheduler(); + /** Call any remaining callbacks on the calling thread */ + void FlushBackgroundCallbacks(); void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload); void TransactionAddedToMempool(const CTransactionRef &ptxn); void BlockConnected(const std::shared_ptr &block, const CBlockIndex *pindex, const std::vector &txnConflicted); void BlockDisconnected(const std::shared_ptr &block, int nBlockHeight); - void NotifyTransactionLock(const CTransaction&); - void UpdatedTransaction(const uint256 &); void SetBestChain(const CBlockLocator &); void Broadcast(CConnman* connman); void BlockChecked(const CBlock&, const CValidationState&); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 0e9f2b526f18..0b084b0a3c33 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1037,9 +1037,9 @@ void CWallet::AddExternalNotesDataToTx(CWalletTx& wtx) const /** * Add a transaction to the wallet, or update it. pIndex and posInBlock should * be set when the transaction was known to be included in a block. When - * posInBlock = SYNC_TRANSACTION_NOT_IN_BLOCK (-1) , then wallet state is not - * updated in AddToWallet, but notifications happen and cached balances are - * marked dirty. + * pIndex == NULL, then wallet state is not updated in AddToWallet, but + * notifications happen and cached balances are marked dirty. + * * If fUpdate is true, existing transactions will be updated. * TODO: One exception to this is that the abandoned state is cleared under the * assumption that any further notification of a transaction that was considered @@ -1053,7 +1053,7 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const uint256 { AssertLockHeld(cs_wallet); - if (posInBlock != -1 && !tx.HasZerocoinSpendInputs() && !tx.IsCoinBase()) { + if (!blockHash.IsNull() && !tx.HasZerocoinSpendInputs() && !tx.IsCoinBase()) { for (const CTxIn& txin : tx.vin) { std::pair range = mapTxSpends.equal_range(txin.prevout); while (range.first != range.second) { @@ -1102,8 +1102,9 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const uint256 } // Get merkle branch if transaction was found in a block - if (posInBlock != -1) + if (!blockHash.IsNull()) { wtx.SetMerkleBranch(blockHash, posInBlock); + } return AddToWallet(wtx, false); } @@ -3552,20 +3553,6 @@ void CReserveKey::ReturnKey() vchPubKey = CPubKey(); } -bool CWallet::UpdatedTransaction(const uint256& hashTx) -{ - { - LOCK(cs_wallet); - // Only notify UI if this transaction is in this wallet - std::map::const_iterator mi = mapWallet.find(hashTx); - if (mi != mapWallet.end()) { - NotifyTransactionChanged(this, hashTx, CT_UPDATED); - return true; - } - } - return false; -} - void CWallet::LockCoin(const COutPoint& output) { AssertLockHeld(cs_wallet); // setLockedCoins diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 6a9e589cb700..d6aa1e2fa43f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -748,8 +748,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface void LoadAddressBookName(const CWDestination& dest, const std::string& strName); void LoadAddressBookPurpose(const CWDestination& dest, const std::string& strPurpose); - bool UpdatedTransaction(const uint256& hashTx) override; - unsigned int GetKeyPoolSize(); unsigned int GetStakingKeyPoolSize(); diff --git a/src/zmq/zmqabstractnotifier.cpp b/src/zmq/zmqabstractnotifier.cpp index 76543a4a797a..53dac44aebc8 100644 --- a/src/zmq/zmqabstractnotifier.cpp +++ b/src/zmq/zmqabstractnotifier.cpp @@ -21,7 +21,3 @@ bool CZMQAbstractNotifier::NotifyTransaction(const CTransaction &/*transaction*/ return true; } -bool CZMQAbstractNotifier::NotifyTransactionLock(const CTransaction &/*transaction*/) -{ - return true; -} diff --git a/src/zmq/zmqabstractnotifier.h b/src/zmq/zmqabstractnotifier.h index 0d3f1fcd4e41..77cf5141e27b 100644 --- a/src/zmq/zmqabstractnotifier.h +++ b/src/zmq/zmqabstractnotifier.h @@ -34,7 +34,6 @@ class CZMQAbstractNotifier virtual bool NotifyBlock(const CBlockIndex *pindex); virtual bool NotifyTransaction(const CTransaction &transaction); - virtual bool NotifyTransactionLock(const CTransaction &transaction); protected: void *psocket; diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp index fffa3bbb023f..19ad4a0eadd7 100644 --- a/src/zmq/zmqnotificationinterface.cpp +++ b/src/zmq/zmqnotificationinterface.cpp @@ -36,10 +36,8 @@ CZMQNotificationInterface* CZMQNotificationInterface::Create() factories["pubhashblock"] = CZMQAbstractNotifier::Create; factories["pubhashtx"] = CZMQAbstractNotifier::Create; - factories["pubhashtxlock"] = CZMQAbstractNotifier::Create; factories["pubrawblock"] = CZMQAbstractNotifier::Create; factories["pubrawtx"] = CZMQAbstractNotifier::Create; - factories["pubrawtxlock"] = CZMQAbstractNotifier::Create; for (std::map::const_iterator i=factories.begin(); i!=factories.end(); ++i) { @@ -181,20 +179,3 @@ void CZMQNotificationInterface::BlockDisconnected(const std::shared_ptr::iterator i = notifiers.begin(); i!=notifiers.end(); ) - { - CZMQAbstractNotifier *notifier = *i; - if (notifier->NotifyTransactionLock(tx)) - { - i++; - } - else - { - notifier->Shutdown(); - i = notifiers.erase(i); - } - } -} diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h index 136724e102c3..b4df973d9781 100644 --- a/src/zmq/zmqnotificationinterface.h +++ b/src/zmq/zmqnotificationinterface.h @@ -28,7 +28,6 @@ class CZMQNotificationInterface : public CValidationInterface void TransactionAddedToMempool(const CTransactionRef& tx) override; void BlockConnected(const std::shared_ptr& pblock, const CBlockIndex* pindexConnected, const std::vector& vtxConflicted) override; void BlockDisconnected(const std::shared_ptr& pblock, int nBlockHeight) override; - void NotifyTransactionLock(const CTransaction &tx) override; void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override; private: diff --git a/src/zmq/zmqpublishnotifier.cpp b/src/zmq/zmqpublishnotifier.cpp index 7541bcf726fa..ee08858fe18e 100644 --- a/src/zmq/zmqpublishnotifier.cpp +++ b/src/zmq/zmqpublishnotifier.cpp @@ -13,10 +13,8 @@ static std::multimap mapPublishNotifi static const char *MSG_HASHBLOCK = "hashblock"; static const char *MSG_HASHTX = "hashtx"; -static const char *MSG_HASHTXLOCK = "hashtxlock"; static const char *MSG_RAWBLOCK = "rawblock"; static const char *MSG_RAWTX = "rawtx"; -static const char *MSG_RAWTXLOCK = "rawtxlock"; // Internal function to send multipart message static int zmq_send_multipart(void *sock, const void* data, size_t size, ...) @@ -164,26 +162,14 @@ bool CZMQPublishHashTransactionNotifier::NotifyTransaction(const CTransaction &t return SendMessage(MSG_HASHTX, data, 32); } -bool CZMQPublishHashTransactionLockNotifier::NotifyTransactionLock(const CTransaction &transaction) -{ - uint256 hash = transaction.GetHash(); - LogPrint(BCLog::ZMQ, "Publish hashtxlock %s\n", hash.GetHex()); - char data[32]; - for (unsigned int i = 0; i < 32; i++) - data[31 - i] = hash.begin()[i]; - return SendMessage(MSG_HASHTXLOCK, data, 32); -} - bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex) { LogPrint(BCLog::ZMQ, "Publish rawblock %s\n", pindex->GetBlockHash().GetHex()); -// XX42 const Consensus::Params& consensusParams = Params().GetConsensus(); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); { LOCK(cs_main); CBlock block; -// XX42 if(!ReadBlockFromDisk(block, pindex, consensusParams)) if(!ReadBlockFromDisk(block, pindex)) { zmqError("Can't read block from disk"); @@ -204,12 +190,3 @@ bool CZMQPublishRawTransactionNotifier::NotifyTransaction(const CTransaction &tr ss << transaction; return SendMessage(MSG_RAWTX, &(*ss.begin()), ss.size()); } - -bool CZMQPublishRawTransactionLockNotifier::NotifyTransactionLock(const CTransaction &transaction) -{ - uint256 hash = transaction.GetHash(); - LogPrint(BCLog::ZMQ, "Publish rawtxlock %s\n", hash.GetHex()); - CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); - ss << transaction; - return SendMessage(MSG_RAWTXLOCK, &(*ss.begin()), ss.size()); -} diff --git a/src/zmq/zmqpublishnotifier.h b/src/zmq/zmqpublishnotifier.h index d6a52e902262..75d0bcba991f 100644 --- a/src/zmq/zmqpublishnotifier.h +++ b/src/zmq/zmqpublishnotifier.h @@ -40,12 +40,6 @@ class CZMQPublishHashTransactionNotifier : public CZMQAbstractPublishNotifier bool NotifyTransaction(const CTransaction &transaction); }; -class CZMQPublishHashTransactionLockNotifier : public CZMQAbstractPublishNotifier -{ -public: - bool NotifyTransactionLock(const CTransaction &transaction); -}; - class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier { public: @@ -58,10 +52,4 @@ class CZMQPublishRawTransactionNotifier : public CZMQAbstractPublishNotifier bool NotifyTransaction(const CTransaction &transaction); }; -class CZMQPublishRawTransactionLockNotifier : public CZMQAbstractPublishNotifier -{ -public: - bool NotifyTransactionLock(const CTransaction &transaction); -}; - #endif // BITCOIN_ZMQ_ZMQPUBLISHNOTIFIER_H